Index: kernel/CHANGES
===================================================================
--- kernel/CHANGES	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/CHANGES	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,8 @@
+CHANGES FROM VERSION 1.0
+========================
+  * smallgmp lib added, gmp lib removed from source distribution
+ 
+  * configure option --without-info added
+
+  * MPtcp:fork mode added, default MPtcp mode is now fork, instead of
+    launch
Index: kernel/COPYING
===================================================================
--- kernel/COPYING	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/COPYING	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,80 @@
+                        SINGULAR version 2-0-0
+			    Singular-kernel
+
+                     University of Kaiserslautern
+
+      Department of Mathematics and  Centre for Computer Algebra
+
+           Authors: G.-M. Greuel, G. Pfister, H. Schoenemann
+
+                        Copyright (C) 1986-2001
+
+
+
+                               *NOTICE*
+
+This program 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 of the License, or (at your
+option) any later version with the following additional restrictions
+(which override any conflicting restrictions in the GPL):
+
+This package is part of the software SINGULAR. The GPL is valid for
+this package, other packages may have other copyrights.
+
+Their copyrights and licences can be found in the accompanying files
+which are distributed along with these packages.
+
+This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA  02111-1307  USA (see GPL)
+
+Please send any comments or bug reports to
+<singular@mathematik.uni-kl.de>.
+
+Please register yourself as a SINGULAR user by sending email to
+<singular@mathematik.uni-kl.de> with the subject line `register'
+if you not already done so.
+
+If you use Singular or parts thereof in a project and/or publish
+results that were partly obtained using SINGULAR, we ask you to cite
+SINGULAR and inform us thereof - see
+`http://www.singular.uni-kl.de/how_to_cite.html', for information on
+how to cite Singular.
+
+Availability
+============
+
+The latest information about SINGULAR is always available from
+`http://www.singular.uni-kl.de'.
+
+Acknowledgements
+================
+
+The development of SINGULAR is directed and coordinated by Gert-Martin
+Greuel, Gerhard Pfister, and Hans Scho"nemann.
+
+Currently, the SINGULAR team has the following members: Olaf Bachmann,
+Anne Fru"bis-Kru"ger, Thomas Keilen, Kai Kru"ger, Christoph Lossen,
+Victor Levandovskyy, Wilfred Pohl, Mathias Schulze, Eric Westenberger,
+and Tim Wichmann.
+
+Past members of the SINGULAR team are: Hubert Grassmann, Wolfgang
+Neumann, Jens Schmidt, Ru"diger Stobbe.
+
+Further contributions to SINGULAR were made by: Thomas Bayer, Isabelle
+Bermejo, Stephan Endrass, Jose Ignacio Farran Martin, Wolfram Decker,
+Philippe Gimenez, Christian Gorzel, Agnes Heydtmann, Dietmar Hillebrand,
+Tobias Hirsch, Martin Lamm, Bernd Martin, Michael Messollen, Thomas
+Nu"ssler, Moritz Wenk.
+
+We should like to acknowledge the financial support given by the
+Volkswagen-Stiftung, the Deutsche Forschungsgemeinschaft and the
+Stiftung fu"r Innovation des Landes Rheinland-Pfalz to the SINGULAR
+project.
+
Index: kernel/ChangeLog
===================================================================
--- kernel/ChangeLog	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/ChangeLog	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,854 @@
+Fri Jan 19 17:56:20 CET 2001 hannes:
+* mod, div for intvec fixed
+* highcorner for global case fixed
+* highcorner for qring fixed
+Tue Feb  1 09:33:35 MET 2000 hannes: summary of changes
+* lift changed: - uses interanlly a different algorithm 
+                  (for SB and NON-SB unified)
+                - can be used with an optional 3rd argument (a matrix name),
+                  if given, the "matrix of units" will be stored in it
+* new command: division (extension of lift)
+     division(M,SM) returns a list (T,U,R) with SM*U+R=M*T
+* new monomial ordering (internal change only): 
+   use of inline function instead of a function pointer
+   (possible point for difficulties: mcompSchrB(polys.cc), pSetSchreyerOrdM
+   (polys.cc))
+* new Library: 
+   spectrum.lib: interface to Stefan Endrass' spectrum routines
+   (Stefan Endrass/H.Schoenemann)
+   (still incomplete, requires a "special" Singular)
+* new Library: 
+   CaMuReg.lib: PROCEDURES FOR COMPUTING CASTELNUOVO-MUMFORD REGULARITY
+   Authors:I.Bermejo/Ph.Gimenez/G.-M.Greuel
+   (not included in the documemtation, not included in the tests)
+* new command: hres 
+    - computes a free resolution of an ideal using Hilbert-driven algorithm
+* new commands: convhull, simplex (M.Wenk)
+  (not documented, not included in the documemtation, not included in the tests)
+  
+Fri Aug 13 13:20:01 MET DST 1999 hannes
+* made fe_fgets_stdin an function pointer instead of a macro
+  ( febase.cc febase.h feread.cc misc.cc sing_mp.cc tesths.cc)
+
+Thu Aug 12 12:57:49 MET DST 1999 hannes
+* integrated "spectrum" by Stefan Endrass, inactive by default
+  (Makefile.in claptmpl.cc feResource.cc iparith.cc mod2.h.in
+  tok.h GMPrat.h GMPrat.cc kmatrix.h multicnt.h multicnt.cc 
+  npolygon.h npolygon.cc semic.h semic.cc spectrum.h spectrum.cc
+  splist.h splist.cc)
+
+Thu Apr 15 19:26:07 MET DST 1999 hannes
+  * start to implement debugger (sdb.h,sdb.cc, febase*, iplib,cc, scanner)
+
+Tue Mar 16 15:54:02 MET 1999 hannes
+  * introduced new routine ERROR(string) (iparith.cc, tok.h)
+  * added trace flag for proc (ipid.cc iplib.cc, febase*)
+
+Mon Mar  8 18:27:26 MET 1999 hannes
+  * access to coeff-description via functions (1. approach)
+    (rChar,  rInternalChar, rField_is_Zp, rField_is_Q,
+     rField_is_R, rField_is_GF, rField_is_Zp_a, rField_is_Q_a,
+     rField_has_simple_inverse)
+
+Wed Dec 16 16:02:07 1998  Jens Schmidt  <schmidt@mathematik.uni-kl.de>
+
+        * clapsing.cc: debugging output modified
+
+Thu Oct 22 14:21:17 MEST 1998 <krueger@mathematik.uni-kl.de>
+        * tesths.cc,subexpr.h,subexpr.cc,ipshell.h,ipshell.cc,iplib.cc
+        * ipid.h,ipid.cc,ipassign.cc,iparith.cc
+          - Added assignment <package>=<package> via ref-counter
+            rewriten killhdl for packages
+          - Added libname,language to packages
+          - exportto(Up,...) 'Up' defined in syMake
+          - listvar() shows toplevel-packages too.
+
+Mon Oct 19 16:01:18 MESZ 1998 hannes
+* hannes: limitations on length of arguments removed (was 200 chars)
+  (iplib.cc)
+
+Thu Oct 15 15:54:05 MEST 1998 <krueger@mathematik.uni-kl.de>
+        * extra.cc,grammar.y,ipid.cc,ipid.h,iplib.cc,ipshell.cc
+        * ipshell.h,ring.cc,structs.h,tesths.cc,mod2.h.in
+          Replaced ring *iiLocalRing[] by a stack (class namerec)
+          To use old method define USE_IILOCALRING in mod2.h
+          Old method incompatible with HAVE_NAMESPACES!
+
+1998-10-14  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * sing_mp.cc (slOpenMPLaunch): added slKill as link function
+        * added --MPrsh to slOpenLaunch
+
+Wed Jul  1 15:25:23 MET DST 1998 hannes:
+* fixed bug with quotient: M:module(0) returns (1), not ([1])
+
+Tue Jun 30 18:30:02 1998  Jens Schmidt  <schmidt@mathematik.uni-kl.de>
+
+        * claptmp.cc (tmax, tmin(Var, Var)): instantiations added
+
+Fri Jun 19 10:01:59 MET DST 1998 hannes
+* hannes: changed back: quot is now from standard.lib,
+                        quotient the C-version
+                        (iparith.cc LIB/standard.lib)
+
+Thu Jun 18 19:27:27 MET DST 1998 hannes
+        * error handling (grammar.y iparith.cc iplib.cc)
+          (leaving of levels, local vars, messages,..)
+          The reason:
+               proc p { intvec w; w[0]; }
+               proc p2 {int i;p();"huhu";}
+               p2(); int i; listvar();
+
+1998-06-13  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * feread.cc: explicit declaration of stuff we need from readline.h
+
+1998-06-12  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * polys.cc: pComp for simple orderings based on only three
+        routines (no variation for # of variables)
+
+        * spolys0.cc (spGSpolyLoop): globally replaced by spSpolyLoop_General
+
+Fri Jun 12 12:11:06 MET DST 1998 hannes
+        * minor optimizations in polys.cc, kutil.* kstd1.cc:
+          pass pointers, not structures to posIn[LT],
+          do not check for NULL in pDeg (as pFDeg does not check)
+
+Wed Jun  3 16:20:22 1998  Jens Schmidt  <schmidt@mathematik.uni-kl.de>
+
+        * Makefile.in (DOCS): target removed
+          (DISTFILES): reference to `$(DOC)' removed
+          (distclean): reference to `$(docdir)' removed
+
+Wed Jun 03 16:46:06 1998    <pohl@FUECHSE>
+
+        * claptmpl.cc: instantiation for operator == (CFFactor, CFFactor)
+          added
+
+Tue Jun  2 17:28:48 MET DST 1998 hannes
+        * introduced /* */ comments
+        * some code cleanups
+Fri May 29 17:00:27 MET DST 1998 hannes
+        * change res to nres (cmd), resu to res(standard.lib)
+          including changes to libs, docs (partially)
+Wed May 27 19:13:10 MET DST 1998 hannes
+        * removed #define HAVE_GMP and non-gmp-parts
+Wed May 20 15:03:28 1998  Jens Schmidt  <schmidt@mathematik.uni-kl.de>
+
+        * LIB/primdec.lib (info): info string reformated
+
+1998-05-19  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * find_exec.c (find_executable): add "." top path, if under WINNT
+        and MSDOS display
+
+        * mmutil.c (mmCheckDBMCB): use _end only #ifdef unix
+
+        * ideals.cc (idDelLmEquals): added idDelLmEqual == simplify(16),
+        and idDelDiv == simplify(32); improved pComparePolys
+
+1998-05-18  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * extra.cc (jjSYSTEM): changed "whoami" --> "Singular", added
+        "nblocks"
+
+Sat May 16 14:14:20 MET DST 1998 hannes
+* avoid multiple objects of the same name (fix keepring)
+Fri May 15 18:02:57 MET DST 1998 hannes
+* added type conversion: ideal(map) -> map
+Fri May 15 13:06:32 MET DST 1998 hannes
+* added syntax: kill (....)
+Thu May 14 16:40:43 MET DST 1998 hannes
+* fixed bug in CoeffOfKBase (ideals.cc)
+Thu May 14 12:01:53 MET DST 1998 hannes
+* a ring with a coeff. field GF(p,n) cannot be constructed
+  without gftables (ring.cc)
+Wed May 13 16:52:09 MET DST 1998 hannes
+        * changed syntax of NOT (does not require () any more)
+Tue May 12 16:58:13 MET DST 1998 hannes
+        * changed return type of option(): none -> string
+Tue May 12 11:57:50 MET DST 1998 hannes
+        * added "lres"
+1998-05-08  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * extra.cc (jjSYSTEM): put all undocumented system calls into
+        #ifdef HAVE_EXTENDED_SYSTEM which is _not_ defined by default
+
+        * exteded system("random") to always return the seed of the random
+        generator
+
+Thu May  7 19:49:34 MET DST 1998 hannes
+        * added syntax rule "proc <name> <arglist> <string> <body>"
+        * speedup for feReadLine
+
+Wed May  6 19:10:59 1998  Jens Schmidt  <schmidt@mathematik.uni-kl.de>
+
+        * find_exec.c (find_executable): bug fix.  Recognizes
+          `../Singular' properly.
+
+Tue May  5 14:06:12 1998  Jens/Kai
+
+        * libparse.l: message fix
+
+Thu Apr 30 19:16:45 MET DST 1998 hannes
+        * fixed "missing e-o-buffer" for long lines in febase.inc
+
+Wed Apr 29 18:26:19 MET DST 1998 hannes
+        * added filed list_length tossyStrategy
+        ( for conversion list <-> resolution): syz.h, syz1.cc, iparith.cc
+1998-04-29  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * mmutil.c (mmGetIndex): new implementation: Use generated lookup
+        table (mmutil.inc) instead of "binary" search on size
+
+Tue Apr 28 19:56:46 MET DST 1998 hannes
+  * ipassign.cc: fixed assignment of resolution to list: need ipMoveId
+1998-04-28  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * kstd2.cc (redHomog): Some more ouput for KDEBUG && TEST_OPT_DEBUG
+
+        * mminit.cc: introduced memory(2) which measures physical memory
+        consumption using the system call sbrk (this never lies!)
+
+Mon Apr 27 18:07:21 MET DST 1998 hannes
+        * use ReAlloc for enlargeT, enlargeL  (kutil.cc)
+Mon Apr 27 16:45:41 MET DST 1998 hannes
+        * fixed conversion of factory 0 to poly NULL (clapconv.cc)
+
+1998-04-27  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * febase.cc (myfread): introduced myfread and myfopen which assure
+        that newlines in text files are always \n
+
+Fri Apr 24 19:14:42 1998  Jens Schmidt  <schmidt@mathematik.uni-kl.de>
+
+        * clapsing.cc (FACTORY_GCD_STAT, singclap_divide_content):
+          dependency on FACTORY_GCD_TEST removed.  Statistics are now done
+           using `FACTORY_GCDSTAT' and `FCATORY_CONTSTAT' which are defined
+           to expand to nothing if `FACTORY_GCD_TIMING' is off.
+
+        * extra.cc (FACTORY_GCD_STAT): dependency on `FACTORY_GCD_TEST'
+          removed.  Includes `gcd_stat.h' in dependency on
+          `FACTORY_CGD_STAT'.
+
+        * extra.cc (jjSYSTEM): new command `gcdstat' in dependency on
+          `FACTORY_GCD_STAT'
+
+Fri Apr 24 18:25:23 MET DST 1998 hannes
+  * fixed bug in maps.cc: size of monom is not pMonomSize but mmGetSpecSize()
+  * changed header in tesths.cc
+  * changed handling of ring changes (polys*.cc ring.cc)
+Thu Apr 23 20:53:06 MET DST 1998 hannes
+  * removed END_GRAMMAR ("RETURN") from iparith.cc, grammar.y
+Thu Apr 23 20:16:24 MET DST 1998 hannes
+  * fixed bug in rKill of Q-rings (ring.cc, polys.cc)
+
+Thu Apr 23 11:12:48 1998  Jens Schmidt  <schmidt@mathematik.uni-kl.de>
+
+        * clapsing.cc (FACTORY_CFTROUT, FACTORY_CFAOUT): stuipd bug fix
+
+        * clapsing.cc (FACTORY_ALGOUT, FACTORY_CFTROUT, FACTORY_CFAOUT):
+          new macros for debugging data transfer to Factory
+           (singclap_divide_content, singclap_alglcm,
+           singclap_algdividecontent): use the new macros
+
+        * clapsing.cc (FACTORY_GCD_TIMING, singclap_divide_content,
+          singclap_alglcm, singclap_algdividecontent): dependency on
+          FACTORY_GCD_TEST removed.  Timings are now done directly using
+          `TIMING_START' and `TIMING_END' which are defined to expand to
+          nothing if `FACTORY_GCD_TIMING' is off.
+
+        * extra.cc (FACTORY_GCD_TIMING): dependency on FACTORY_GCD_TEST
+          removed
+
+        * longalg.cc (naNormalize): gcd calculation depends on #define
+          `FACTORY_GCD_TEST'
+
+Wed Apr 22 09:42:35 MET DST 1998 hannes
+  * several changes concerning stdfac
+    (kstdfac.cc, kutil.cc kutil.h)
+
+Tue Apr 21 15:19:10 MET DST 1998 hannes/jens
+  * gdc in Q(a) returns "not implemented" (clapsing.cc)
+
+Tue Apr 21 12:30:44 1998  Jens Schmidt  <schmidt@mathematik.uni-kl.de>
+
+        * clapsing.cc  (singclap_gcd): checks for `NULL' removed
+
+        * clapsing.cc, extra.cc (FACTORY_GCD_TEST, FACTORY_GCD_STAT,
+           FACTORY_GCD_DEBOUT, FACTORY_GCD_TIMING): new #defines for gcd
+          testing
+        * clapsing.cc (singclap_divide_content, singclap_alglcm,
+          singclap_algdividecontent): code added for factory testing.
+            Wrapped by #defines `FACTORY_GCD_TEST', `FACTORY_GCD_STAT',
+           `FACTORY_GCD_DEBOUT', and `FACTORY_GCD_TIMING'.
+        * extra.cc (jjSYSTEM): code added for factory testing.  Wrapped
+          by #defines `FACTORY_GCD_TEST' and `FACTORY_GCD_TIMING'.
+
+Fri Apr 17 09:53:53 MET DST 1998 hannes
+ * fixed a minor but very nasty bug: nlSetMap was resetting npPrimeM
+    (longrat.cc)
+
+1998-04-21  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * mmprivat.h: Got rid off mmheap.cc, "inlined" mmPutMemory
+
+        * longalg.h:  Exponents in parameter (polys) are typedef'ed to
+        EXPONENT_TYPE
+
+1998-04-20  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * mmallocb.c: Merged with mmheap.c.
+
+1998-04-16  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * mpsr_PutPoly.cc: Took out normalization of rational numbers
+        before they are put -- might have side effects
+
+        * extra.cc: added system("--option") which returns value of
+        option; in debug mode: system("OptionValues") lists all option
+        values
+
+        * sing_mp.cc: use long option names for MP link options
+        * MPtcp:launch: Uses find_exec as default application
+
+        *  tesths.cc: New (handling of) command line options (long
+        options, usage of getopt_long): Parse more than one argument
+        script, etc ..
+        *  added getopt.[c,h]for parsing of command lines
+
+        * mod2.h.in, configure.in: Got rid off str* tests
+
+1998-04-07  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * mpsr_Put.cc (mpsr_PutDump): dump does not dump LIB string any more
+
+        * extra.cc (jjSYSTEM): added System("whoami") to return full
+        executable pathname of running Singular
+
+Tue Apr  7 10:27:50 MET DST 1998 hannes
+        * fixed scanner bug: ignoring { and } in <block> (scanner.l)
+
+1998-04-06  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * spSpolyLoop.h: neww calling interface for spGetSpolyLoop
+
+        * kstd1.cc (kNF): moved strat->ak field initailization out of
+        initBuchMora into single routines
+
+        * febase.cc (feGetSearchPath): added feGetSearchPath; changed
+        algorithm for searching files: $SINGULARPATH -> relative to
+        executable -> burnt-in locations
+        * added find_exec.c to get absolute pathname of executable
+
+Mon Apr  6 14:23:52 1998  Jens Schmidt  <schmidt@mathematik.uni-kl.de>
+
+        * claptmpl.cc: instantiation for `tabs()' added
+
+Sat Apr  4 00:52:58 MET DST 1998 Kai Krueger <krueger@mathematik.uni-kl.de>
+        * iplib.cc libparse.cc libparse.h libparse.l misc.cc LIB/*.lib
+          Changed help for libraries.
+
+Wed Apr  1 20:55:15 MET DST 1998 hannes
+        * mpsr_Tok.cc,tok.h: minor fix, removed VERBOSE_CMD
+        * iparith.cc ipconv.cc: added conversion list <-> resolution
+        * lists.cc, syz1.cc : fixed bug in conversion (list<->res.):
+          handling "empty" case
+        * scanner.l: added option: %option always-interactive
+
+Tue Mar 31 10:47:06 MET DST 1998 hannes
+        * feread.cc: fixed handling of empty history
+        * clapsing.cc: fixed gcd(0,..) and gcd(..,0) -> pOne()
+        * febase.h/febase.inc: renaming of scanner variables
+          ( yy_blocklineno, yy_noeof)
+        * febase.inc: increased speed in feReadLine
+        * minor changes in scanner/grammar/iparith.cc (example)
+
+1998-03-27  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * longalg.cc (naDBTest): fixed lines for number tests
+
+        * added spSpolyLoop.inc to repository
+
+        * algmap.cc (maAlgpolyMap): fixed bug which changed preimage
+
+1998-03-23  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * taged version 1.1.7 -- unconditional fast version
+
+        * polys-impl.cc, polys.cc: No COMP_FAST any more
+
+        * Makefile.in: Introduced variable PERL, set by configure
+
+        * kstdfac.cc (kStratCopy): kModW iv is not copied, but just the
+        pointer is set
+
+1998-03-18  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * Makefile.in: added Singularb target for bprof
+
+        * polys-impl.h, polys-comp.h: Cleaned up COMP_FAST and related
+        #defines
+
+1998-03-16  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * polys-impl.h: no #define COMP_FAST
+
+        * configure.in,Makefile.in: check for flex -P; increased version
+        number to 1.1.7
+
+Fri Mar 13 16:16:27 MET 1998 hannes
+  * fixed: Singular crashed while changing the minpoly in GF(q)
+    (ipassign.cc)
+
+Fri Mar  6 13:27:45 MET 1998 Kai Krueger <krueger@mathematik.uni-kl.de>
+        * new: libparse.l,libparse.cc,utils.cc,ytils.h
+          scanner for a quick check of singular-libraries.
+        * Makefile.in,mod2.h.in,iplib.cc,structs.h,subexpr.h
+          use a scanner when loading libraries.
+        * grammar.y,ipassign.cc,subexpr.h
+          procinfo: added position of end of proc-definition
+                    added flag for 'static'-proc (proc that can only be used
+                          in the library they are defined).
+        * LIB: deform.lib,finvar.lib,hnoether.lib,normal.lib,presolve.lib
+               primdec.lib,tex.lib
+          made fixes requested by libparse (s.a. brackets, ....)
+
+1998-03-04  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * febase.h: added macro assume()
+
+        * spSpolyLoop.cc: Automatic generation of SpolyLoops using
+        spSpolyLoop.pl
+
+        * kstd*.cc: New calling interface to get SpolyLoop
+
+        * ring.h: Introduced rOrderType_t
+
+Mon Mar  2 16:18:25 MET 1998 hannes
+   * changed handling of "echo" in examples: do not report file + lineno
+     (febase.inc,lib0lib.res, inoutlib.res, mem.res, homlib.res)
+
+Fri Feb 27 15:02:10 MET 1998 hannes
+   * new input scheme: many modifications to febase.h, febase.inc,
+     febase.cc, scanner.l, grammar.y, iplib.cc
+
+Tue Feb 17 18:43:11 MET 1998 hannes
+        * added additional factorization check after redTail
+          (kstdfac.cc)
+
+1998-02-17  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * longalg.cc (napWrite): made it globally available to support
+        FACTORY_DEBUG_OUT
+
+        * clapsing.cc (singclap_algdividecontent): inserted
+        FACTORY_DEBUG_OUT
+
+Mon Feb 16 10:43:38 MET 1998 hannes
+   * added HAVE_TCL to ring.cc
+
+Mon Feb  9 12:28:21 MET 1998 hannes
+   * added tests for coeff-filed GF(q), added stbus for GF(q)-conversion
+     (clapconv.cc clapsing.cc clapconv.h)
+
+Tue Jan 27 19:45:19 MET 1998 hannes
+   *  bug fixes for TEST_MAC_ORDER (binom.* polys-impl.h, spSpolyLoop.cc)
+      (binom.* poly-impl.* spSpolyLoop.cc)
+
+Mon Jan 26 18:40:43 MET 1998 hannes
+   * changes in iparith.cc for define: PROC_BUG
+     useful, if c++ cannot type cast proc variables
+
+Sat Jan 24 18:21:24 MET 1998 hannes
+   * bug fixes for TEST_MAC_ORDER (binom.* polys-impl.h, spSpolyLoop.cc)
+
+Sat Jan 17 18:56:34 MET 1998 hannes
+   * changes for TEST_MAC_ORDER, part 3 (binom.cc, binom.h, spSpolyLoop.cc)
+
+Sat Jan 17 18:21:15 MET 1998 hannes
+        * removed duplicate _memcpyW from mmalloc.c
+        * fixed type cast in iplib.cc
+        * changes for TEST_MAC_ORDER, part 2 (binom.cc, binom.h, spSpolyLoop.cc)
+
+Fri Jan 16 15:30:07 MET 1998 Kai Krueger <krueger@mathematik.uni-kl.de>
+        * extra.cc,febase.cc,febase.inc,grammar.y,iparith.cc
+        * ipassign.cc,ipid.cc,ipid.h,iplib.cc,ipshell.h,misc.cc
+        * mpsr_Put.cc,mpsr_Put.h,silink.cc,structs.h,subexpr.cc,subexpr.h
+        * tesths.cc
+          Implementation of new proc-scheme done.
+
+Fri Jan 16 14:51:07 MET 1998 Kai Krueger <krueger@mathematik.uni-kl.de>
+        * Makefile.in,tests/mpcheck,teste/comparecheck:
+          fixed use of correct Singular during checks
+
+Fri Jan 16 09:23:07 MET 1998
+        * changes for TEST_MAC_ORDER, part 1 (hannes)
+
+Wed Jan 14 15:36:04 1998  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * polys-impl.h (pMonAddFast): fixed handling of component
+
+        * mmutil.c: added _memcpyW for DO_DEEP_PROFILE
+
+        * binom.h: #undef TEST_MAC_ORDER as default
+
+        * polys-impl.h: fixes to make things clearer and for
+          NO_EXP_VECTOR_OPS
+
+        * Makefile.in (Singularp): use static linking for
+
+Fri Dec 19 17:22:26 1997  Jens Schmidt  <schmidt@mathematik.uni-kl.de>
+
+        * claptmpl.cc: template instantiation for `Array<REvaluation>'
+          added
+
+        * fglmcomb.cc, fglmhom.cc, fglmzero.cc, claptmpl.cc: #include
+          directives fixed (templates/list.h renamed to
+           templates/ftmpl_list.h)
+
+Thu Dec 18 15:23:29 MET 1997
+        * hannes:
+        - removed type "binary" and handling routines
+        (iparith.cc ipid.cc subexpr.cc tok.h)
+        - fixed m16ex (doc/examples.doc)
+        - fixed reference (doc/singular.doc, doc/start.doc)
+
+Wed Dec 17 09:47:58 MEZ 1997 Kai Krueger <krueger@mathematik.uni-kl.de>
+        * test/dbm_test.[in/out]: rewrite of dbm-tests.
+
+Tue Dec 16 16:59:41 1997  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * polys-impl.h: Introduced COMP_NO_EXP_VECTOR_OPS -- which turns
+        off "vector techniques" of monomial operations, i.e. does
+        everything exponent-wise
+
+Mon Dec 15 23:31:56 1997  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * polys-impl.h: Various small bug - fixes and changes in
+          preparation of COMP_FAST merge: hilbert series, maps are
+          ok; sres and syz are still buggy; small things still need to be
+          checked;
+
+Fri Dec 12 15:38:19 1997  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * mmallocb.c (mmDBFreeBlock): introduced UNREG_MEM_PATTERN which,
+          when defined, inserts unregular memory pattern in
+          allocated/freed memory
+
+        * all: changed dangerous pNew calls to pInit's
+
+Fri Dec  5 18:43:47 MET 1997
+        * hannes: fix to ideals.cc: avoid pGetExp(p,0)
+
+Thu Dec  4 16:13:31 MEZ 1997 Kai Krueger <krueger@mathematik.uni-kl.de>
+        * ndbm.cc: don't replace bcopy by memcpy if possible, otherwise
+          the database (>1024 bytes) will be corrupted.
+        - added check for bcopy() in configure.
+
+Wed Dec  3 16:14:51 1997  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * Many changes to prepare for implementation of fast comparison
+                  schemes: Here are only a few:
+        - added file polys-impl.h which implements low-level poly stuff
+        - removed file polys2.cc, added polys-impl.cc
+        - added Singularp target to Make
+        - prepared configure for setting of exponent type
+        - got rid of as many direct p->exp[..] accesses as possible
+        - added file spSpolyLoop.cc spSpolyLoop.h polys-comp.h
+        * polys-impl.h: if you defined COMP_FAST, then fast polynomial
+                  comparsions are eanbled (still needs a lot of debugging)
+
+
+Fri Oct 31 05:45:25 1997  Olaf Bachman  <bachman@bombelli.dm.unipi.it>
+
+        * polys1.cc et al: got rid of p[Get/Set]ExpV routines, provided
+                  pCopy2 instead
+
+Wed Oct  8 12:22:47 1997  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * increased version number to 1.1.3
+
+        * ndbm.cc: Solaris compatibility: #define bcopy bzero, bcmp;
+                  #include <fcntl.h>
+        * configure.in: added check for fcntl.h sys/types.h sys/stat.h, ucblib
+          ensured that either lgmp or lsmallgmp is in $LIBS
+
+Tue Sep 16 15:45:44 MET DST 1997
+        * hannes: changed/corrected/clean naNormalize, naLcm, pCleardenom, pContent
+            (polys1.cc, longalg.cc)
+            added singclap_alglcm (clapconv.cc, clapsing.cc)
+
+Tue Sep  9 11:05:28 MET DST 1997
+        * hannes: flex-staff is now in febase.inc
+               changed tutorial (doc/examples.doc, version-no: doc/tutor.tex)
+
+Fri Aug 15 11:44:13 MESZ 1997  Kai Krueger <krueger@mathematik.uni-kl.de>
+        * ndbm.cc: fix open-bug  for dos
+          default mode of open is ascii, we need binary mode.
+
+Thu Aug 14 18:04:04 1997  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+        and anne
+
+        * Makefile.in, mod2.h.in, configure.in: cleaned up for dos
+          cross-compilation
+
+Tue Aug 12 19:08:20 MET DST 1997
+        * hannes: added nExactDiv to numbers
+        * hannes: corrected open bug in sing_dbm.cc (could only "r")
+                  simplified sing_dbm.cc (many tests already in silink.cc)
+                  added "mod" (as an alias to "%")
+                  updated singular.doc: div/mod
+                                        DBM: links
+        * hannes: ANSI-conversion in ndbm.cc
+          (added return types, include files)
+
+Fri Aug  8 14:54:28 1997  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * Makefile.in ndbm.[cc,h]: Together with krueger: Added files
+          ndbm.[cc,h]; no longer linking with libdbm, instead,
+          user supplied files; added dbm_test; small changes to sing_dbm.cc
+
+Fri Aug  8 12:56:44 MET DST 1997
+        * hannes: introduced "div" for integer division
+          grammar.*, iparith.cc, singular.doc
+        * changed version to 1.1.2/August
+
+Thu Aug  7 14:51:59 1997  Olaf Bachmann  <obachman@mathematik.uni-kl.de>
+
+        * mpsr_Get.cc (GetCopCommandLeftv): made +/* to binary ops
+
+        * longrat.[h,cc]: added number   nlInit(number i) to initialize a
+                  number, i.e. get it into the right Singular state
+
+Wed Jul 16 12:57:22 MET DST 1997: hannes
+        * introduced '.singularrc', modified loading of satndard.lib
+          (tesths.cc)
+Tue Jul 15 13:57:46 MET DST 1997: hannes
+        * added call to proc in from standard.lib in tesths.cc
+
+Wed Jul  9 17:50:23 MET DST 1997: hannes/siebert
+        * added new type (resolution)
+        -> extra.cc, ipid.cc, iparith.cc, ipconv.cc, syz.h, syz1.cc
+
+Fri Jun 20 12:18:10 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * tesths.cc (main): fixed condition of mprs_ttGen execution
+
+Thu Jun 19 10:49:10 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * mpsr_Put.h: corrected efinitions of MP_AnnotReqValTree, MP_AnnotReqValNode
+
+Tue Jun 17 11:47:47 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * Makefile.in (Singular): added mod2.h to dependencies of iparith.inc
+
+        * tok.h: no discrimination of mac for inline definition any more
+
+Wed Jun 11 09:56:05 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * mpsr_Tok.cc (cmd_dictcops): changed names of some MP_Cops
+
+        * longrat.[cc,h], tesths.cc, Makefile.in, configure.in:
+          added support for smallgmp
+
+Tue Jun 10 17:25:28 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * sing_mp.cc: Got rid off warnings, when incomplete link specs
+
+Thu Jun  5 15:16:19 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * tests/mpcheck: added check for correct remote shell
+
+Sun May 25 14:06:12 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * configure.in: Fixed handling of CXXFLAGS -- it is not touched if
+          set as env var
+
+Fri May 23 11:40:14 1997  Olaf Bachmann  <obachman@schlupp.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * Makefile.in: Changed dist target to cp; make distclean
+
+Wed May 21 08:56:19 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * mpsr_Tok.cc: fixed dependencies/generation of mpsr_Tok.inc
+
+        * tesths.cc (main): made -v option gmp v1.3 clean
+
+Tue May 20 14:02:42 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * misc.cc: Put #include <factory.h> into #ifdef HAVE_FACTORY brackets
+
+* hannes: ipshell.cc: fixed a bug in iiExport (multiple exports in rings)
+          subexpr.cc: implemented sleftv::Copy for ring/qring
+          syz1.cc: added missing idSkipZeros to LaScala*
+
+Wed May 14 16:40:19 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * Makefile.in: changed mpcheck.data so that the brain-dead sed on
+          the suns does not mess up the output on files with long lines
+
+Tue May 13 11:32:41 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * claptmpl.cc: changed template initializiation of libfac, so that
+          class.cc and tmpl_inst.h does not need to be included
+
+Mon May 12 16:48:14 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * misc.cc: Added / to Help_File and Info_File
+
+Tue May  6 08:29:57 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * added factorycheck target in Makefile.in
+
+        * Makefile.in (configure): took out rules which automatically
+          reruns autoconf. Print out warning, instead
+
+        * misc.cc, configure.in, mod2.h.in:
+            added SINGULAR_INFODIR to search for info files
+
+        * configure.in: Added AC_SUBST(WITH_LIBFAC, WITH_MP, WITH_FACTORY)
+
+Mon May  5 10:31:15 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * #include "factory" instead of include "singfactory"
+
+        * mod2.h.in: define buildin_gmp, if HAVE_GMP and macintosh
+
+Sun May  4 11:14:44 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * Added make target mpcheck; Update INSTALL file
+
+        * mpsr_PutPoly.cc (PutRationalNumber): Normalize if number->s == 0
+          and not if number->s == 2
+
+        * mpsr_GetPoly.cc (GetGaloisNumber): Introduced special routines,
+          since npInit op in GetModuloNumber messed things up
+
+Sat May  3 00:07:55 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * Makefile.in (CPPFLAGS): put -I. before other CPPFLAGS
+
+        * febase.cc (feFopen): fixed bug in opening library from
+          SINGULAR_DATADIR: SINGULAR_DATADIR is appended to
+          getenv("SINGULARPATH")
+
+        * small mpsr Changes to reflect some name changes of MP Dicts
+
+        * configure.in Makefile.in: new scheme for updating Makefile mod2.h
+          based on time-stamps
+
+Fri May  2 17:29:32 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * mpsr.h: reflected changes of MP version 1.1.2 (Dicts in MP.h)
+
+        * Fixed small bug in configure.in
+
+Mon Apr 28 21:00:07 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * Added README, INSTALL, COPYING file to distribution
+
+        * tesths.cc (main): slightly changed Singular banner; fixed
+          display of version number
+
+Fri Apr 25 16:59:31 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * fixed configure.in s.t. sprintf test is correct
+
+        * Changed SingularPath to SINGULARPATH
+
+        * fixed sys/times.h and sys/time.h confusion
+
+        * Various changes to reflect new configure (versions defined in
+          configure.in, changed HAVE_LIBFACTORY into HAVE_FACTORY, data
+          dir is pasted from configure into mod2.h and used from there in
+          feFopen.
+
+        * Added configure facility, repalced mod2.h by mod2.h.in Makefile
+          by Makefile.in
+
+Fri Apr 18 09:47:22 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * silink.cc (DumpAsciiIdhdl): LIB string is dumped without type
+          declaration
+
+        * mpsr_Get.cc (InitIdentifierLeftv): used mpsr_SetCurrRing(r,
+          TRUE) so that pOne works if no ring did previously exist.
+
+        * iparith.cc: Added jjPROC3.
+
+Tue Apr 15 12:07:17 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * silink.cc (slStandardInit): changed Ascii type specifyer from
+          "ascii" to "Ascii" for consistency
+
+        * iparith.cc : added #else branch to #ifdef HAVE_FGLM in proc table
+
+        *  (extra.cc): system("sh",command) returns exit status of command
+
+Thu Apr 10 11:59:41 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * remote quit is now arranged using MP_CopMpQuit
+
+        * Updated mpsr_* files for new naming convention of MP v:1.1.2
+
+Tue Apr  8 10:43:48 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * Reimplemented link structures. Cleaned it up. Introduced assignment
+link = link. Fixed some bugs in asciidump. Made proc's work for MP links.
+
+Sat Mar 29 16:01:39 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * silink.cc (DumpQring): Takes care of dumping a Qring
+        (slInit): enable ascii link specification of the form "filename
+        mode:w"
+
+Fri Mar 28 14:12:05 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * Added routines dump(link) and getdump(link) for ascii and MP
+          links
+
+        * ipconv.cc (dConvertTypes): added int->module conversion so that
+          'module m = 0' works
+
+        * iparith.cc (jjVAR1): added LINK_CMD to list of typeof(...)
+
+Thu Mar 27 21:20:20 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * added real time timer (rtimer) analog to timer
+
+        * added command-line option "-d ticks_per_second" and "-m
+          min_displayed_time_in_sec" and chahnged timer accordingly
+
+        * added some #ifdef HAVE_FGLM in fglm*.cc
+
+
+Wed Mar 26 14:02:15 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * added reference counter to links, updated slKill, slCopy, slInit
+        * various small bug fixes for Batch mode
+
+Mon Mar 24 14:27:26 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * sing_mp.cc (slOpenWriteMPFile): Added append and write mode to
+          open MP:file
+
+Sun Mar 23 20:48:41 1997  Olaf Bachmann  <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * mpsr_Get.cc (InitIdentifierLeftv): Fixed bug which did not do
+          pSetm(p) after creating a poly out of a variable
+
+Thu Mar 20 11:57:00 1997  Olaf Bachmann  <obachman@schlupp.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * sing_mp.cc (slInitBatchLink): initialized silink such that
+          l->argv[0] == "MP:connect" (otherwise, slInitMP failed)
+
+Wed Mar 19 15:38:08 1997  Olaf Bachmann  <obachman@schlupp.mathematik.uni-kl.de (Olaf Bachmann)>
+
+        * hannes fixed maFindPerm to reflect new names <->parameter scheme
+
+        * sing_mp.cc (mpsr_IsMPLink): fixed it
+
+        * Makefile (tags): added target tags
+
Index: kernel/ChangeLog.plural
===================================================================
--- kernel/ChangeLog.plural	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/ChangeLog.plural	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,51 @@
+29.11.02
+        ref for ncstruct introduced,
+	used in extra.cc ("PLURAL"), rCopy0, rKill
+	new routine ncKill
+
+29.11.02
+	qring q=system("twostd",i); is introduced and tested
+	file: exterior1.tst
+	todo: forbid the use of non-twosided ideals
+
+6.12.02
+	DONE: option(redTail) is implemented and tested
+	file: exterior2.tst
+	DONE(11.12.02) todo: in twostd, running from qring should be
+	done another std() in order to get reduced result
+	
+	DONE: buckets in multiplication (p_Mult_mm, mm_Mult_p)
+	version 1.17 - add cvs -m "buckets added", not
+	just nCopy
+	todo: syz(i) with the canonical method, think about
+	Schreyer and LaScala (double homogenization)
+	Print(p) at gr_kstd2.cc:877 is commented out
+	
+23.01.03-
+31.01.03
+	Updated multiplication: 
+	now we search for the shortest path with nc_uu_Mult_ww_horvert
+	An old code is called nc_uu_Mult_ww_vert, is used by default.
+	
+	Further on, we should compute metrics.
+
+	A function added:
+	matrix ncMatPrint(int a, int b, ring r, int metric)
+  	/* returns matrix with the info on noncomm multiplication */
+Before these changes, we copied the exec to Singular.Jan.
+
+31.01.03
+	DONE syz, nres, mres;
+	small problems with minres.
+
+until
+17.03.03
+	fixed: minres, ideal multiplication, maps, syz
+	balanced the use of buckets in mult and bracket
+	added quasicommutative stuff in multiplication
+	gained about 30% speedup
+
+18.03.03
+	fixed: extra "type print" in ring.cc
+        new strategy of bucket used in bracket 
+
Index: kernel/GMPrat.cc
===================================================================
--- kernel/GMPrat.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/GMPrat.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,561 @@
+// ----------------------------------------------------------------------------
+//  GMPrat.cc
+//  begin of file
+//  originally written by Gerd Sussner, sussner@mi.uni-erlangen.de
+//  copied by Stephan Endrass, endrass@mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#define  GMPRAT_CC
+
+#include "mod2.h"
+
+#ifdef HAVE_SPECTRUM
+
+#ifdef   GMPRAT_PRINT
+#include <iostream.h>
+#ifndef  GMPRAT_IOSTREAM
+#include <stdio.h>
+#endif
+#endif
+
+#include <stdlib.h>
+#include <math.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "GMPrat.h"
+
+// ----------------------------------------------------------------------------
+//  Miscellaneous
+// ----------------------------------------------------------------------------
+
+Rational Rational::save;    // dummy variable
+
+// ----------------------------------------------------------------------------
+//  disconnect a rational from its reference
+// ----------------------------------------------------------------------------
+
+void    Rational::disconnect( )
+{
+    if( p->n>1)
+    {
+        p->n--;
+        p = new rep;
+    }
+    else
+    {
+        mpq_clear(p->rat);
+    }
+    mpq_init(p->rat);
+}
+
+// ----------------------------------------------------------------------------
+//  Constructors
+// ----------------------------------------------------------------------------
+
+Rational::Rational( )
+{
+    p = new rep;
+    mpq_init( p->rat );
+}
+
+Rational::Rational( int a )
+{
+    p = new rep;
+    mpq_init( p->rat );
+    mpq_set_si( p->rat,(long int)a,1 );
+}
+
+Rational::Rational( const Rational& a )
+{
+    a.p->n++;
+    p=a.p;
+}
+
+// ----------------------------------------------------------------------------
+//  Constructors with two arguments: numerator and denominator
+// ----------------------------------------------------------------------------
+
+Rational::Rational(const Rational& a, const Rational& b)
+{
+    p=new rep;
+    mpq_init(p->rat);
+    mpq_div(p->rat, a.p->rat, b.p->rat);
+}
+
+Rational::Rational(int a, int b)
+{
+    if (b<0) a=-a;
+    p=new rep;
+    mpq_init(p->rat);
+    mpq_set_si(p->rat,(long int) a,(unsigned long int) abs(b));
+    mpq_canonicalize(p->rat);
+}
+
+// ----------------------------------------------------------------------------
+//  Destructor
+// ----------------------------------------------------------------------------
+
+Rational::~Rational()
+{
+  if (--p->n==0){
+    mpq_clear(p->rat);
+    delete p;
+  }
+}
+
+// ----------------------------------------------------------------------------
+//  Assignment operators
+// ----------------------------------------------------------------------------
+
+Rational& Rational::operator=(int a)
+{
+  disconnect();
+  mpq_set_si(p->rat,(long int) a,1);
+  return *this;
+}
+
+Rational& Rational::operator=(const Rational& a)
+{
+  a.p->n++;
+  if (--p->n==0){
+    mpq_clear(p->rat);
+    delete p;
+  }
+  p=a.p;
+  return *this;
+}
+
+// ----------------------------------------------------------------------------
+//  Numerator and denominator
+// ----------------------------------------------------------------------------
+
+Rational Rational::get_num( )
+{
+    Rational erg;
+
+    mpq_set_num( erg.p->rat,mpq_numref( p->rat ) );
+
+    return  erg;
+}
+
+int Rational::get_num_si( )
+{
+    return  mpz_get_si( mpq_numref( p->rat ) );
+}
+
+Rational Rational::get_den( )
+{
+    Rational erg;
+
+    mpq_set_num( erg.p->rat,mpq_denref( p->rat ) );
+
+    return  erg;
+}
+
+int Rational::get_den_si( )
+{
+    return  mpz_get_si( mpq_denref( p->rat ) );
+}
+
+// ----------------------------------------------------------------------------
+//  Casting
+// ----------------------------------------------------------------------------
+
+Rational::operator int()
+{
+  mpz_t
+    h;
+  long int
+    ret_val;
+
+  mpz_init(h);
+  mpz_tdiv_q(h,mpq_numref(p->rat),mpq_denref(p->rat));
+  ret_val=mpz_get_si(h);
+  mpz_clear(h);
+
+  return ret_val;
+}
+
+// ----------------------------------------------------------------------------
+//  Unary minus
+// ----------------------------------------------------------------------------
+
+Rational
+Rational::operator-()
+{
+  Rational
+    erg;
+
+  mpq_neg(erg.p->rat,p->rat);
+  return erg;
+}
+
+Rational operator - ( const Rational &r )
+{
+  Rational
+    erg;
+
+  mpq_neg(erg.p->rat,r.p->rat);
+  return erg;
+}
+
+// ----------------------------------------------------------------------------
+//  Inverse
+// ----------------------------------------------------------------------------
+
+Rational
+Rational::operator~()
+{
+  Rational
+    erg;
+
+  mpq_inv(erg.p->rat,p->rat);
+  return erg;
+}
+
+// ----------------------------------------------------------------------------
+//  +=, -= ...
+// ----------------------------------------------------------------------------
+
+Rational&
+Rational::operator+=(const Rational &a)
+{
+  mpq_set(save.p->rat,p->rat);
+  disconnect();
+  mpq_add(p->rat,save.p->rat,a.p->rat);
+  return *this;
+}
+
+Rational&
+Rational::operator-=(const Rational &a)
+{
+  mpq_set(save.p->rat,p->rat);
+  disconnect();
+  mpq_sub(p->rat,save.p->rat,a.p->rat);
+  return *this;
+}
+
+Rational&
+Rational::operator*=(const Rational &a)
+{
+  mpq_set(save.p->rat,p->rat);
+  disconnect();
+  mpq_mul(p->rat,save.p->rat,a.p->rat);
+  return *this;
+}
+
+Rational&
+Rational::operator/=(const Rational &a)
+{
+  mpq_set(save.p->rat,p->rat);
+  disconnect();
+  mpq_div(p->rat,save.p->rat,a.p->rat);
+  return *this;
+}
+
+// ----------------------------------------------------------------------------
+//  Increment and decrement
+// ----------------------------------------------------------------------------
+
+Rational&
+Rational::operator++()
+{
+  mpq_set(save.p->rat,p->rat);
+  *this=1;
+  mpq_add(p->rat,p->rat,save.p->rat);
+  return *this;
+}
+
+Rational
+Rational::operator++(int)
+{
+  Rational
+    erg(*this);
+
+  mpq_set(save.p->rat,p->rat);
+  *this=1;
+  mpq_add(p->rat,p->rat,save.p->rat);
+  return erg;
+}
+
+Rational&
+Rational::operator--()
+{
+  mpq_set(save.p->rat,p->rat);
+  *this=1;
+  mpq_sub(p->rat,save.p->rat,p->rat);
+  return *this;
+}
+
+Rational
+Rational::operator--(int)
+{
+  Rational
+    erg(*this);
+
+  mpq_set(save.p->rat,p->rat);
+  *this=1;
+  mpq_sub(p->rat,save.p->rat,p->rat);
+  return erg;
+}
+
+// ----------------------------------------------------------------------------
+//  Relational operators
+// ----------------------------------------------------------------------------
+
+bool operator<(const Rational& a,const Rational& b)
+{
+  if (mpq_cmp(a.p->rat,b.p->rat)<0) return true;
+  return false;
+}
+
+bool operator<=(const Rational& a,const Rational& b)
+{
+  if (mpq_cmp(a.p->rat,b.p->rat)>0) return false;
+  return true;
+}
+
+bool operator>(const Rational& a,const Rational& b)
+{
+  if (mpq_cmp(a.p->rat,b.p->rat)>0) return true;
+  return false;
+}
+
+bool operator>=(const Rational& a,const Rational& b)
+{
+  if (mpq_cmp(a.p->rat,b.p->rat)<0) return false;
+  return true;
+}
+
+bool operator==(const Rational& a,const Rational& b)
+{
+  if (mpq_equal(a.p->rat,b.p->rat)) return true;
+  return false;
+}
+
+bool operator!=(const Rational& a,const Rational& b)
+{
+  if (mpq_equal(a.p->rat,b.p->rat)) return false;
+  return true;
+}
+
+// ----------------------------------------------------------------------------
+//  Ostream
+// ----------------------------------------------------------------------------
+
+#ifdef GMPRAT_PRINT
+ostream& operator<< (ostream& s,const Rational& a)
+{
+    char *snum,*sdenom;
+
+    snum   = mpz_get_str( NULL,10,mpq_numref(a.p->rat) );
+    sdenom = mpz_get_str( NULL,10,mpq_denref(a.p->rat) );
+
+    if( sdenom[0] == '1' && sdenom[1] == '\0' )
+    {
+        #ifdef GMPRAT_IOSTREAM
+            s << snum;
+        #else
+            fprintf( stdout,snum );
+        #endif
+    }
+    else
+    {
+        #ifdef GMPRAT_IOSTREAM
+            s << snum << "/" << sdenom;
+        #else
+            fprintf( stdout,snum );
+            fprintf( stdout,"/" );
+            fprintf( stdout,sdenom );
+        #endif
+    }
+
+    //free( snum );
+    //free( sdenom );
+
+    return s;
+}
+#endif
+
+unsigned int Rational::length( ) const
+{
+    char *snum = (char*)NULL;
+    char *sden = (char*)NULL;
+
+    snum = mpz_get_str( snum,10,mpq_numref( p->rat ) );
+    sden = mpz_get_str( sden,10,mpq_denref( p->rat ) );
+
+    int length = strlen( snum );
+
+    if( sden[0] != '1' || sden[1] != '\0' ) length += strlen( sden ) + 1;
+
+    free( snum );
+    free( sden );
+
+    return  length;
+}
+
+// ----------------------------------------------------------------------------
+//  Operators
+// ----------------------------------------------------------------------------
+
+Rational
+operator+(const Rational& a,const Rational &b)
+{
+  Rational
+    erg(a);
+
+  return erg+=b;
+}
+
+Rational
+operator-(const Rational& a,const Rational &b)
+{
+  Rational
+    erg(a);
+
+  return erg-=b;
+}
+
+Rational
+operator*(const Rational& a,const Rational &b)
+{
+  Rational
+    erg(a);
+
+  return erg*=b;
+}
+
+Rational pow( const Rational& a,int e )
+{
+    Rational erg(1);
+
+    for( int i=0; i<e; i++ )
+    {
+        erg *= a;
+    }
+    return erg;
+}
+
+Rational operator/(const Rational& a,const Rational &b)
+{
+  Rational
+    erg(a);
+
+  return erg/=b;
+}
+
+int sgn(const Rational& a)
+{
+  return mpq_sgn(a.p->rat);
+}
+
+Rational
+abs(const Rational& a)
+{
+  Rational
+    erg;
+
+  if (mpq_sgn(a.p->rat)<0)
+    mpq_neg(erg.p->rat,a.p->rat);
+  else
+    mpq_set(erg.p->rat,a.p->rat);
+  return erg;
+}
+
+Rational gcd( const Rational &a,const Rational &b )
+{
+    if( a == 0 )
+    {
+        if( b == 0 )
+        {
+            return  (Rational)1;
+        }
+        else
+        {
+            return  abs( b );
+        }
+    }
+    else if( b == 0 )
+    {
+        return  abs( a );
+    }
+
+    Rational erg;
+
+    mpz_gcd( mpq_numref( erg.p->rat ),
+            mpq_numref( a.p->rat ),mpq_numref( b.p->rat ) );
+    mpz_gcd( mpq_denref( erg.p->rat ),
+            mpq_denref( a.p->rat ),mpq_denref( b.p->rat ) );
+
+    //mpq_canonicalize( erg.p->rat );
+
+    return  abs( erg );
+}
+
+Rational gcd( Rational *a,int n )
+{
+    if( n == 1 )
+    {
+        return  a[0];
+    }
+
+    Rational g = gcd( a[0],a[1] );
+
+    for( int i=2; i<n; i++ )
+    {
+        g = gcd( g,a[i] );
+    }
+
+    return  g;
+}
+
+Rational lcm( const Rational &a,const Rational &b )
+{
+    if( a == 0 )
+    {
+        return b;
+    }
+    else if( b == 0 )
+    {
+        return a;
+    }
+
+    return a*b/gcd(a,b);
+}
+
+Rational lcm( Rational *a,int n )
+{
+    if( n == 1 )
+    {
+        return  a[0];
+    }
+
+    Rational g = lcm( a[0],a[1] );
+
+    for( int i=2; i<n; i++ )
+    {
+        g = lcm( g,a[i] );
+    }
+
+    return  g;
+}
+
+double  Rational::complexity( ) const
+{
+    double num = mpz_get_d( mpq_numref( p->rat ) );
+    double den = mpz_get_d( mpq_denref( p->rat ) );
+
+    if( num < 0 ) num = -num;
+    if( den < 0 ) den = -den;
+
+    return  ( num > den ? num : den );
+}
+
+#endif /* HAVE_SPECTRUM */
+// ----------------------------------------------------------------------------
+//  GMPrat.cc
+//  end of file
+// ----------------------------------------------------------------------------
Index: kernel/GMPrat.h
===================================================================
--- kernel/GMPrat.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/GMPrat.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,95 @@
+// ----------------------------------------------------------------------------
+//  GMPrat.h
+//  begin of file
+//  originally written by Gerd Sussner, sussner@mi.uni-erlangen.de
+//  copied by Stephan Endrass, endrass@mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#ifndef  GMPRAT_H
+#define  GMPRAT_H
+
+#include "gmp.h"
+
+class Rational
+{
+    struct rep
+    {
+        mpq_t rat;
+        int   n;
+        rep() { n=1; }
+    };
+
+    rep             *p;
+    static Rational save;
+
+    void disconnect();
+
+    public:
+
+    Rational( );
+    Rational( int );
+    Rational( const Rational& );
+    Rational( const Rational&,const Rational& );
+    Rational( int,int );
+    ~Rational( );
+
+    Rational& operator = ( int );
+    Rational& operator = ( char *s );
+    Rational& operator = ( const Rational& );
+
+    unsigned int length( ) const;
+    Rational get_num( );
+    Rational get_den( );
+    int      get_num_si( );
+    int      get_den_si( );
+    operator int( );
+
+    Rational  operator - ( );
+    Rational  operator ~ ( );
+    Rational& operator += ( const Rational& );
+    Rational& operator -= ( const Rational& );
+    Rational& operator *= ( const Rational& );
+    Rational& operator /= ( const Rational& );
+    Rational& operator ++ ( );
+    Rational  operator ++ ( int );
+    Rational& operator -- ( );
+    Rational  operator -- ( int );
+
+    friend Rational operator - ( const Rational& );
+
+    friend bool operator <  ( const Rational&,const Rational& );
+    friend bool operator <= ( const Rational&,const Rational& );
+    friend bool operator >  ( const Rational&,const Rational& );
+    friend bool operator >= ( const Rational&,const Rational& );
+    friend bool operator == ( const Rational&,const Rational& );
+    friend bool operator != ( const Rational&,const Rational& );
+
+    #ifdef GMPRAT_PRINT
+    friend ostream& operator<<( ostream&,const Rational& );
+    #endif
+
+    friend int      sgn ( const Rational& );
+    friend Rational abs ( const Rational& );
+    friend Rational pow ( const Rational&,int );
+
+    double   complexity( ) const;
+
+    friend Rational gcd ( const Rational&, const Rational& );
+    friend Rational lcm ( const Rational&, const Rational& );
+    friend Rational gcd ( Rational*, int );
+    friend Rational lcm ( Rational*, int );
+};
+
+Rational operator + ( const Rational&, const Rational& );
+Rational operator - ( const Rational&, const Rational& );
+Rational operator * ( const Rational&, const Rational& );
+Rational operator / ( const Rational&, const Rational& );
+
+#endif /* GMPRAT_H */
+
+// ----------------------------------------------------------------------------
+//  GMPrat.h
+//  end of file
+// ----------------------------------------------------------------------------
+
Index: kernel/HOWTO.FindMemoryHoles
===================================================================
--- kernel/HOWTO.FindMemoryHoles	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/HOWTO.FindMemoryHoles	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,18 @@
+Here is a first short HowTo on how to locate memory holes in Singular:
+1.) Make sure you build with -DOM_TRACK=5 (e.g. use Singulart, Singularg).
+2.) Use system("mtrack", [<level>, [<filename>]]) to get a report about
+    unused memory, where
+ * 0 <= level <= 5 determines how many stackframes per not freed
+   address are printed (default is 5 -- 0 only prints a summary)
+ * <filename> is name of file where report should be output to
+   (defaults to stdout).
+3.) Running 'regress.cmd -tt <level> file.tst' creates the file
+    'file.mtrack.unused' with report of not freed addresses (<level> has 
+    same meaning as above).
+4.) Within the C/C++ sources, Use 'omMarkAsStatic(addr)' to mark an
+    address as static, i.e. as an address which is ok if it is not
+    freed. Addresses marked this way are not reported by
+    system("mtrack",...) (resp. regress.cmd -tt).
+5.) For some more details, see also extra.cc: system("mtrack", ...)
+
+
Index: kernel/INSTALL
===================================================================
--- kernel/INSTALL	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/INSTALL	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,283 @@
+			 Singular version 1.0
+		     University of Kaiserslautern
+     Department of Mathematics (or, Centre for Computer Algebra)
+	  Authors: G.-M. Greuel, G. Pfister, H. Schoenemann
+		  (C) 1986-1997 All Rights Reserved
+
+		INSTALLATION INSTRUCTIONS FOR SINGULAR 
+		======================================
+
+This file contains instructions on how to install Singular. For
+general information about Singular, see the file 'README' contained in this
+directory. For copying informations, see the file 'COPYING' contained
+in this directory. For comments, problems or bugs, please send mail to
+singular@mathematik.uni-kl.de. If you receive this file as part of a
+complete Singular distribution, see also the README, COPYING, and
+INSTALL files contained in the top directory of the full Singular
+distribution.
+
+Installation for the Impatient 
+==============================
+Being in the directory which contains this file, type
+
+  ./configure
+  make 
+
+Basic Installation
+==================
+
+
+The `configure' shell script in this directory attempts to guess
+correct values for various system-dependent variables used during
+compilation.  It uses those values to create the `Makefile' from the
+file 'Makefile.in' and the file 'mod2.h' (which contains
+system-dependent definitions) from the file 'mod2.h.in'. Finally, it
+creates a shell script `config.status' that you can run in the future
+to recreate the current configuration, a file `config.cache' that
+saves the results of its tests to speed up reconfiguring, and a file
+`config.log' containing compiler output (useful mainly for debugging
+`configure').
+
+The file `configure.in' is used to create `configure' by a program
+called `autoconf'.  You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile Singular is:
+
+  1. `cd' to the directory containing the Singular's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile Singular.
+
+  3. Optionally, type `make check' to run the self-tests that come with
+     the Singular (in the subdirectory tests).
+
+  4. Type `make install' to install the (executable) Singular program,
+     Singular's info files (from the subdirectory docs), and
+     Singular's program libraries written in Singular's
+     architecture-independent and interpreted programming language
+     (from the subdirectory LIB).
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+  6. Other make targets include:
+     'dist'      : Creates a distribution of all source files of
+                   Singular.
+     'TAGS'      : Creates/updates a tags table for Singular's source
+                   files.
+     'info'      : Regenerates Singular's Info file.
+     'dvi'       : Generates the file docs/Singular.dvi -- a DVI file
+                   of Singular's user manual 
+     'uninstall' : Deletes all installed files that the 'install'
+                   target created (i.e. Singular's executable program,
+                   Singular's info file, and Singular's libraries)
+     'check'     : Tests basic Singular functionality
+
+Compilers and Options
+=====================
+
+You need an ANSI-C++ and ANSI-C compiler for compiling Singular. We
+strongly recommend that you use the GNU C/C++ (gcc) compiler. If you
+have gcc installed on your system, configure will automatically find
+and use it for building Singular. Otherwise, configure will try to
+find another ANSI-C and ANSI-C++ compiler. To use explicitly use an
+alternative compiler, or to set some unusual options for compilation
+or linking that the `configure' script does not know about, you can
+give `configure' initial values for variables by setting them in the
+environment.  Using a Bourne-compatible shell, you can do that on the
+command line like this:
+     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+     CXX=CC CXXFLAGS=+O3 LIBS=-liostream ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+
+Installation Names
+==================
+
+By default, `make install' will install the Singular program in
+`/usr/local/bin', Singular's info files in `/usr/local/info', and
+Singular's program libraries in '/usr/local/share'.  You can
+specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PATH'. You can specify an alternative
+directory where the Singular program is installed by giving configure
+the option `--bindir=PATH'. For Singular's info files, use
+'--infodir=PATH' and for Singular's program libraries, use
+'--datadir=PATH'. Make sure that PATH is an _absolute_ (not relative)
+pathname. 
+
+
+Optional Features
+=================
+
+Singular's configure script pays attention to the following
+`--with-PACKAGE' options where PACKAGE can be:
+
+  'readline' : Uses the readline library for some fancy display.
+	       Requires that libreadline.a and the readline header
+	       files are installed on your system. If these files were
+	       not found, then Singular is build without readline.
+
+  'dbm'      : Uses the dbm library for DBM links. Requires that
+               libdbm.a or libgdbm.a is installed on your system. If
+               this library is not found, then Singular is built
+               without DBM and DBM links are disabled. 
+
+  'info'     : Uses the 'info' program for displaying the Singular
+               documentation on a 'help' copmmand. This requires that
+               the 'info' programm is installed on your system. If
+               this program is not found, the a built-in display
+               routine is used.
+
+  'MP'       : Uses the MP library for MP links. Requires that
+               libgmp.a, libMP.a, libMPT.a and gmp.h, MP.h, MPT.h are
+               installed on your system. If these files are not found,
+               then Singular is built without MP, and MP links ar disabled.
+
+  'factory'  : Uses the Factory library for polynomial
+               factorizations. Requires that libsingcf.a, factory.h
+               and the factory template files are installed on your
+               system. If these files are not found, then Singular is
+               built without factory, and polynomial factorization
+               routines are disabled.
+
+  'libfac'   : Uses the libfac library for characteristic set
+               computations. Requires libsingfac.a and libfac.h to be
+               installed on your system. If these files are not found,
+               then Singular is built without libfac and
+               characteristic set routines are disabled. 
+
+By default, configure runs as if all the above '--with-PACKAGE'
+options were given and searches through the given includedir and the
+system's default include directories for header files, and through the
+given libdir and through the system's default library directory for
+the library files. If one of the requirements for a PACKAGE is not
+met, configure prints a warning message and builds Singular
+without the respective PACKAGE, disabling its functionality. To
+explicitly built Singular without one of the above PACKAGEs, give
+configure (an) appropriate '--without-PACKAGE' option(s). See the
+README file about instructions on how to obtain the above PACKAGEs.
+
+Furthermore, the following '--with-apint=PACKAGE' option is
+recognized, where package can be:
+  'gmp'      : Uses the GNU multiple precision library for arbitrary
+               integer precision arithmetic. This results in the best
+               performance. Requires that libgmp.a and gmp.h
+               are installed on your system.
+  'smallgmp' : Uses the smallgmp library for for arbitrary
+               integer precision arithmetic. This results in a
+               performance which is slightly worse than that of the
+               original gmp library.
+  'buildin'  : Uses Singular's internal integer arithmetic
+               routines. The resulting performance is poor in
+               comparison to gmp or smallgmp and the usage of MP,
+               factory, or libfac is automatically disbaled.
+
+By default, configure checks whether it can find gmp or smallgmp (in
+that order) and use the respective package, if found. If none is
+found, then Singular's internal arbitrary precision routines are used.
+
+
+System Requirements
+===================
+
+The following requirements have to be met by your system, so that you
+can build Singular:
+  1. The condition (sizeof(int) == 4) has to be true.
+  2. The condition (sizeof(void*) == sizeof(long)) has to be true.
+  3. The condition (-2 >> 1 == -1) has to be true.
+  4. The headers limits.h and unistd.h have to be installed.
+  5. The standard C headers and libraries have to be installed.
+
+
+Operation Controls
+==================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+     Use and save the results of the tests in FILE instead of
+     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
+     debugging `configure'.
+
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.
+
+`--version'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--help'
+     Prints  the following summary of the options to `configure', and exits.
+
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print `checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [/mnt/amd/users/urmel/singular/obachman/Singular/Singular/..]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+--enable and --with options recognized:
+  --without-readline   do not use readline for fancy display
+  --without-MP         do not use MP (disables MP links)
+  --without-dbm        do not use dbm (disables DBM links)
+  --without-info       do not use info for help (use buildin help, instead)
+  --without-dld        do not use dld (disables dynamic linking)
+  --without-factory    do not use factory (disables poly factorization)
+  --without-libfac     do not use libfac (disables primary decompositions)
+  --with-apint=PACKAGE    use PACKAGE for arbitary integer arithmetic
+                          where PACKAGE can be gmp, smallgmp, or buildin
Index: kernel/README
===================================================================
--- kernel/README	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/README	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,136 @@
+			 Singular version 1.0
+		     University of Kaiserslautern
+     Department of Mathematics        Centre for Computer Algebra
+	  Authors: G.-M. Greuel, G. Pfister, H. Schoenemann
+		  (C) 1986-1997 All Rights Reserved
+
+		   README FILE FOR SINGULAR KERNEL
+		   ===============================
+
+This directory contains the source files for the Singular kernel and
+the following subdirectories:
+ 
+  'doc'	  -- contains sources for Singular documentation files 
+  'check' -- contains a small Singular self-test
+  'LIB'   -- contains Singular libraries written in Singular's
+             programming language
+
+See the following files in this directory
+  'INSTALL' -- for information on how to install Singular
+  'COPYING' -- for copying and license information
+
+See below for an overview of Singular, and for distribution and
+support information.
+
+If you receive this file as part of a complete Singular distribution,
+see also the README.src, COPYING.src, and INSTALL files contained in the top
+directory of the full Singular distribution.
+
+
+Overview of Singular
+====================
+Singular is a special-purpose computer algebra system for commutative
+algebra and algebraic geometry. The main features of Singular are:
+
+ * Computations in very general rings (polynomial rings, localizations
+   of rings at a prime ideal, tensor products of rings) over many
+   ground fields (rational numbers, mod p numbers, Galois fields,
+   transcendental/algebraic extensions) and monomial orderings (all
+   standard monomial orderings, including matrix orderings)
+
+ * Very fast standard (resp. Groebner) bases computations
+
+ * Polynomial factorization, resultant, and gcd computations
+
+ * Large variety of implemented related algorithm: FGLM,
+   Hilbert-driven, Factorizing Buchberger; Minimal resolutions,
+   Primary decomposition; Usual ideal theoretic operations; standard
+   combinatorial algorithms.
+
+ * Efficient and flexible communication links based on the MP
+   protocol and library
+
+ * Easy-to-use, command-driven user-interface
+
+ * Intuitive, C-like programming language
+
+ * Extensive libraries of procedures, written in Singular's
+   programming language
+
+ * Written in C/C++. Available as source and binary for some hard- and
+   software platforms (including most Un*x variants, MS-DOG, MacOS)
+
+
+Distribution of Singular
+========================
+The newest version of Singular is always available by anonymous ftp
+from 
+	     www.mathematik.uni-kl.de:/pub/Math/Singular
+
+Binary versions of Singular for common hard- and software
+platforms are contained in the files Singular-1.0.<platform>.gz where
+<platform> is, for example, 'linux', 'SunOS', etc.  See the file
+README.bin for more information about the distribution of Singular
+binaries.
+
+Architecture - independent files (such as libraries written in the
+Singular programming language, and the Singular documentation) are
+distributed as Singular-1.0-share.tar.gz. See the file README.share
+for more information. 
+
+In general, Singular is only available as binary program. For
+exceptions, you may contact us at
+        singular@mathematik.uni-kl.de
+
+The source is distributed in two versions:
+  1. A full source distribution of Singular is contained in
+     Singular-full-1.0.tar.gz.  This (gzip'ed and tar'ed) file
+     contains the source code, documentation, and supporting data
+     files for the Singular kernel, and for all add-on packages,
+     i.e. for the GMP, MP, Factory, and Libfac libraries.
+
+  2. A kernel source distribution of Singular can be found in
+     Singular-1.0.tar.gz This (gzip'ed and tar'ed) contains the
+     sources, documentation and supporting data files for Singular,
+     only, i.e., it comes WITHOUT the sources for any of the add-on
+     packages.
+
+Singular's performance is best, if it is linked with the GNU Multiple
+precision library (GMP), instead of the smallgmp library which is
+contained in the full source distribution. Furhtermore, Singular's
+terminal i/o is most convenient if it is linked with the GNU readline
+library.  The GMP library and the readline library is available at
+ftp.gnu.ai.mit.edu or its mirrors. You have to have these library
+already installed, before Singular can be linked with them. For more
+information, see the file README.src contained in this directory.
+
+The MP library library is avialbale from mcs.kent.edu:/pub/MP/
+For further information on MP, see also
+http://symbolicnet.mcs.kent.edu/areas/protocols/mp.html
+
+The factory and libfac library are available from
+www.mathematik.uni-kl.de:/pub/Math/
+
+Documentation to Singular is distributed as:
+Singular-1.0.dvi.gz	 - Reference manual in dvi format
+Tutorial.dvi.gz		 - Singular tutorial in dvi format
+Singular-1.0.ps.gz	 - Reference manual in postscript format
+Tutorial.dvi.gz		 - Singular tutorial in postscript format
+singular.hlp.gz		 - Reference manual in Info format
+Singular-1.0.html.tar.gz - Reference manual in html format
+
+
+More information about Singular: Comments, Questions, Bug Reports
+=================================================================
+
+More and up-to-date information about Singular is always available
+from 
+	   http://www.mathematik.uni-kl.de/~wwwzca/Singular
+We very much welcome any comments, questions, and bug reports. Please
+contact us at  
+		    singular@mathematik.uni-kl.de
+
+
+GOOD LUCK and ENJOY!                         Your Singular team.
+
+
Index: kernel/RULES
===================================================================
--- kernel/RULES	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/RULES	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,6 @@
+* never use fopen, but myfopen, in order to open text files
+
+* call rComplete after constructing a ring
+
+* never allocate memory with 0 as size request
+
Index: kernel/algmap.cc
===================================================================
--- kernel/algmap.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/algmap.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,324 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: algmap.cc,v 1.1.1.1 2003-10-06 12:15:50 Singular Exp $ */
+/*
+* ABSTRACT - the mapping of polynomials from rings with
+* 'alg' numbers
+*/
+
+#include "mod2.h"
+#include "omalloc.h"
+#include "polys.h"
+#include "numbers.h"
+#include "longalg.h"
+#include "ring.h"
+#include "febase.h"
+#include "maps.h"
+#include "algmap.h"
+
+
+static poly maLongalg1Fetch(poly res, poly p0, ring r0, int n,
+                            int t, BOOLEAN *nom)
+{
+  napoly a0, b0;
+  poly q0, q1 = NULL;
+  int i, j, m = r0->N;
+
+  if (naGetDenom0(pGetCoeff(p0)) != NULL)
+  {
+    *nom = TRUE;
+    return res;
+  }
+  a0 = naGetNom0(pGetCoeff(p0));
+  do
+  {
+    q0 = pInit();
+    pSetComp(q0,p_GetComp(p0, r0));
+    if (t!=0)
+    {
+      pGetCoeff(q0) = (number)omAlloc0Bin(rnumber_bin);
+      b0 = naGetNom0(pGetCoeff(q0)) = napNew();
+      napGetCoeff(b0) = nacCopy(napGetCoeff(a0));
+      for (i=1; i<=t; i++)
+      {
+        napSetExp(b0,i,napGetExpFrom(a0,i,r0));
+      }
+    }
+    else
+    {
+      pGetCoeff(q0) = nCopy(napGetCoeff(a0));
+    }
+    for (i=m; i>0; i--)
+    {
+      pSetExp(q0,i, p_GetExp( p0,i,r0));
+    }
+    j = t;
+    for (i=m+1; i<=n; i++)
+    {
+      j++;
+      pSetExp(q0,i, napGetExpFrom(a0,j,r0));
+    }
+    pSetm(q0);
+    q1 = pAdd(q1, q0);
+    a0 = napNext(a0);
+  }
+  while (a0 != NULL);
+  return pAdd(res, q1);
+}
+
+static poly maLongalg2Fetch(poly res, poly p0, ring r0, int n, int s,
+                            int t, BOOLEAN *nom)
+{
+  poly q0;
+  int i, j;
+  napoly b0;
+  napoly a0 = NULL, b1 = NULL;
+
+  if (s!=0)
+  {
+    if (naGetDenom0(pGetCoeff(p0)) != NULL)
+    {
+      *nom = TRUE;
+      return res;
+    }
+    a0 = naGetNom0(pGetCoeff(p0));
+  }
+  q0 = pInit();
+  pSetComp(q0,p_GetComp(p0, r0));
+  for (i=n; i>0; i--)
+  {
+    pSetExp(q0,i, p_GetExp(p0,i,r0));
+  }
+  pSetm(q0);
+  do
+  {
+    b0 = napNew();
+    if (s!=0)
+    {
+      napGetCoeff(b0) = nacCopy(napGetCoeff(a0));
+      for (i=1; i<=s; i++)
+      {
+        napSetExp(b0,i, napGetExp(a0,i));
+      }
+    }
+    else
+    {
+      napGetCoeff(b0) = nacCopy(pGetCoeff(p0));
+    }
+    j = n;
+    for (i=s+1; i<=t; i++)
+    {
+      j++;
+      napSetExp(b0,i, p_GetExp(p0,j,r0));
+    }
+    if (s==0)
+    {
+      pGetCoeff(q0)=(number)omAlloc0Bin(rnumber_bin);
+      naGetNom0(pGetCoeff(q0)) = b0;
+      return pAdd(res, q0);
+    }
+    b1 = napAdd(b1, b0);
+    a0 = napNext(a0);
+  }
+  while (a0 != NULL);
+  if (pGetCoeff(q0)==NULL)
+    pGetCoeff(q0) = (number)omAlloc0Bin(rnumber_bin);
+  naGetNom0(pGetCoeff(q0)) = b1;
+  return pAdd(res, q0);
+}
+
+/*2
+* return Fe(preimage)
+* Fe : k(y(1),..,y(s))[x(1),..,x(m)] -> k(y(1),..,y(t))[x(1),..,x(n)]
+*      with:
+*      s+m = t+n,
+*      Fe(y(i)) = y(i), i = 1,..,min(s,t),
+*      Fe(x(i)) = x(i), i = 1,..,min(m,n),
+*      and
+*      1. for s>t: Fe(y(i)) = x(i+n-t), i = t+1,..,s
+*      2. for m>n: Fe(x(i)) = y(i+t-n), i = n+1,..,m
+*/
+poly maAlgpolyFetch(ring R, poly preimage)
+{
+  BOOLEAN nom=FALSE;
+  int m, n, s, t;
+  poly p0, result=NULL;
+
+  if (preimage == NULL)
+  {
+    return NULL;
+  }
+  m = R->N;
+  n = currRing->N;
+  s = rPar(R);
+  t = rPar(currRing);
+  if ((m+s) != (n+t))
+  {
+    WerrorS("no algfetch possible");
+    return NULL;
+  }
+  if (n == m)
+  {
+    return pCopy(preimage);
+  }
+  p0 = preimage;
+  if (s > t)
+  {
+    while (p0!=NULL)
+    {
+      result = maLongalg1Fetch(result, p0, R, n, t, &nom);
+      if (nom)
+      {
+        goto err_algfetch;
+      }
+      pIter(p0);
+    }
+  }
+  else
+  {
+    while (p0!=NULL)
+    {
+      result = maLongalg2Fetch(result, p0, R, n, s, t, &nom);
+      if (nom)
+      {
+        goto err_algfetch;
+      }
+      pIter(p0);
+    }
+  }
+  return result;
+
+err_algfetch:
+  pDelete(&result);
+  WerrorS("denominator in algnumber");
+  return NULL;
+}
+
+static poly maLongalgMap(poly res, ring r, poly p0, int s, int t,
+                         BOOLEAN *nom, poly monpart, ideal F)
+{
+  number cc;
+  napoly a0, b0;
+  poly q, q0, q1 = NULL;
+  int i;
+
+  if (s == 0)
+  {
+    if (t!=0)
+    {
+      nNew(&cc);
+      b0 = napNew();
+      napGetCoeff(b0) = pGetCoeff(p0);
+      naGetNom0(cc) = b0;
+      pMult_nn(monpart,cc);
+      napGetCoeff(b0) = NULL;
+      nDelete(&cc);
+    }
+    else
+    {
+      pMult_nn(monpart,pGetCoeff(p0));
+    }
+    pSetCompP(monpart, p_GetComp(p0,r));
+    return pAdd(res, monpart);
+  }
+  if (naGetDenom0(pGetCoeff(p0)) != NULL)
+  {
+    *nom = TRUE;
+    WerrorS("denominator in algnumber");
+    pDelete(&monpart);
+    pDelete(&res);
+    return NULL;
+  }
+  a0 = naGetNom0(pGetCoeff(p0));
+  do
+  {
+    q = pInit();
+    if (t!=0)
+    {
+      pGetCoeff(q) = (number)omAlloc0Bin(rnumber_bin);
+      b0 = naGetNom0(pGetCoeff(q)) = napNew();
+      napGetCoeff(b0) = nacCopy(napGetCoeff(a0));
+    }
+    else
+    {
+      pGetCoeff(q) = nCopy(napGetCoeff(a0));
+    }
+    for(i=0; i<s; i++)
+    {
+      if (napGetExpFrom(a0,i+1,r) != 0)
+      {
+        if (F->m[i]!=NULL)
+        {
+          q0 = pPower(pCopy(F->m[i]),napGetExpFrom(a0,i+1,r));
+          q = pMult(q, q0);
+        }
+        else
+        {
+          pDelete(&q);
+          break;
+        }
+      }
+    }
+    q1 = pAdd(q1, q);
+    a0 = napNext(a0);
+  }
+  while (a0 != NULL);
+  q1 = pMult(q1,monpart);
+  pSetCompP(q1,p_GetComp(p0,r));
+  return pAdd(res, q1);
+}
+
+number maNumberOne(number x)
+{
+  return nInit(1);
+}
+
+/*2
+* return Ma(preimage)
+* Ma : k(y(1),..,y(s))[x(1),..,x(m)] -> k(y(1),..,y(t))[z(1),..,z(n)]
+* the ideals F = f_1,..,f_s and G = g_1,..,g_m in k(y(1),..,y(t))[z(1),..,z(n)]
+* are as follows:
+* f_i = Ma(y(i)), g_i = Ma(x(i))
+*/
+poly maAlgpolyMap(ring R, poly preimage, ideal F, ideal G)
+{
+  BOOLEAN nom=FALSE;
+  int m, s, t;
+  poly p0, monpart, result = NULL;
+
+  if (preimage == NULL)
+  {
+    return NULL;
+  }
+  m = R->N;
+  if (m != IDELEMS(G))
+  {
+    WerrorS("error 1 in algmap");
+    return NULL;
+  }
+  s = rPar(R);
+  if ((s!=0) && (s != IDELEMS(F)))
+  {
+    WerrorS("error 2 in algmap");
+    return NULL;
+  }
+  t = rPar(currRing);
+  p0 = preimage;
+  poly pr=NULL;
+  while (p0!=NULL)
+  {
+    poly pr=pNext(p0);
+    p0->next=NULL;
+    monpart = maEval((map)G, p0, R, maNumberOne);
+    result = maLongalgMap(result, R, p0, s, t, &nom, monpart, F);
+    pTest(result);
+    if (nom)
+    {
+      return NULL;
+    }
+    p0->next = pr;
+    p0=pr;
+  }
+  return result;
+}
Index: kernel/algmap.h
===================================================================
--- kernel/algmap.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/algmap.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,15 @@
+#ifndef ALGMAP_H
+#define ALGMAP_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: algmap.h,v 1.1.1.1 2003-10-06 12:15:50 Singular Exp $ */
+/*
+* ABSTRACT:
+*/
+#include "structs.h"
+
+poly maAlgpolyFetch(ring R, poly preimage);
+poly maAlgpolyMap(ring R, poly preimage, ideal F, ideal G);
+
+#endif
Index: kernel/check_aso.pl
===================================================================
--- kernel/check_aso.pl	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/check_aso.pl	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,84 @@
+#!/usr/local/bin/perl
+###########################################################################
+# $Id: check_aso.pl,v 1.1.1.1 2003-10-06 12:15:50 Singular Exp $
+
+###########################################################################
+##
+## FILE: check_aso.pl
+## PURPOSE: checks source files for Alloc(sizeof(..)) statements and
+##          fixes them, if requested
+## AUTHOR: obachman (10/99)
+##
+
+$Usage = <<EOT;
+$0 [-fh] file(s)
+Checks source files for Alloc(sizeof(..)) statements and 
+fixes them, if -f
+EOT
+
+# parse command-line options  
+while  (@ARGV && $ARGV[0] =~ /^-/) 
+{
+  $_ = shift(@ARGV);
+  if (/^-h/)
+  {
+    print STDOUT $Usage;
+    exit(0);
+  }
+# $fix = 1 if /^-f/;
+}
+
+
+# process file 
+while (<>)
+{
+  # Check for Alloc(sizeof(..)), Free(..,sizeof(..))
+  if (/(^|[^\w])(Alloc|Alloc0|AllocAligned|AllocAligned0)\s*\(\s*sizeof\s*\(\s*([^\)]*)\s*\)\s*\)/ 
+      ||
+      /(^|[^\w])(Free|FreeAligned)\s*\(.*,\s*sizeof\s*\(\s*([^\)]*)\s*\)\s*\)/)
+  {
+    $what = $3;
+    $alloc = $2;
+    $what =~ s/^\s*//;
+    $what =~ s/\s*$//;
+    if ($what !~ /^\w[\w\d]*$/)
+    {
+      print STDERR "Warning: Argument $what to $alloc does not match \w[\w\d]* at $ARGV:$.\n";
+    }
+    else
+    {
+      # error if inside sizeof(..) is weird
+      print STDERR "Warning: $alloc(sizeof($what)) found at $ARGV:$.";
+      if ($fix)
+      {
+	s/sizeof\s*\(\s*$what\s*\)/$what/; 
+	$what = $alloc."SizeOf";
+	s/$alloc/$what/;
+	$fixed = 1;
+	print " (fixed)\n";
+      }
+      else
+      {
+	print "\nRun '$0 -f $ARGV' to fix\n";
+      }
+    }
+  }
+  $content .= $_ if $fix;
+} 
+continue
+{
+  if (eof)
+  {
+    close ARGV;
+    if ($fix && $fixed)
+    {
+      print STDERR "Creating $ARGV.bak and fixing $ARGV\n";
+      system("cp $ARGV $ARGV.bak");
+      open(ARGV, ">$ARGV");
+      print ARGV $content;
+      close(ARGV);
+      $fixed = 0;
+    }
+  }
+}
+
Index: kernel/clapconv.cc
===================================================================
--- kernel/clapconv.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/clapconv.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,757 @@
+// emacs edit mode for this file is -*- C++ -*-
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+// $Id: clapconv.cc,v 1.1.1.1 2003-10-06 12:15:50 Singular Exp $
+/*
+* ABSTRACT: convert data between Singular and factory
+*/
+
+
+#include "mod2.h"
+#ifdef HAVE_FACTORY
+#include "omalloc.h"
+#include "structs.h"
+#define SI_DONT_HAVE_GLOBAL_VARS
+#include "clapconv.h"
+#include "numbers.h"
+#include "modulop.h"
+#include "longalg.h"
+#include "polys.h"
+#include "febase.h"
+#include "ring.h"
+
+static void convRec( const CanonicalForm & f, int * exp, poly & result );
+
+static void convRecAlg( const CanonicalForm & f, int * exp, napoly & result );
+
+static void convRecPP ( const CanonicalForm & f, int * exp, poly & result );
+static void conv_RecPP ( const CanonicalForm & f, int * exp, poly & result, ring r );
+
+static void convRecPTr ( const CanonicalForm & f, int * exp, napoly & result );
+
+static void convRecAP ( const CanonicalForm & f, int * exp, poly & result );
+
+static void convRecTrP ( const CanonicalForm & f, int * exp, poly & result, int offs );
+
+static void convRecGFGF ( const CanonicalForm & f, int * exp, poly & result );
+
+static number convClapNSingAN( const CanonicalForm &f);
+
+CanonicalForm
+convSingNClapN( number n )
+{
+  CanonicalForm term;
+  /* does only work for Zp, Q */
+  if ( getCharacteristic() != 0 )
+  {
+    Off(SW_USE_EZGCD);
+    term = npInt( n );
+  }
+  else
+  {
+    if ( ((int)n) & 1 )
+    {
+      term = ((int)n) >>2;
+    }
+    else
+    {
+      if ( n->s == 3 )
+      {
+        MP_INT dummy;
+        mpz_init_set( &dummy, &(n->z) );
+        term = make_cf( dummy );
+      }
+      else  if ( n->s == 1 )
+      {
+        MP_INT num, den;
+        On(SW_RATIONAL);
+        mpz_init_set( &num, &(n->z) );
+        mpz_init_set( &den, &(n->n) );
+        term = make_cf( num, den, false );
+      }
+      else
+      { // assume s == 0
+        MP_INT num, den;
+        mpz_init_set( &num, &(n->z) );
+        mpz_init_set( &den, &(n->n) );
+        term = make_cf( num, den, true );
+      }
+    }
+  }
+  return term;
+}
+
+number
+convClapNSingN( const CanonicalForm & n)
+{
+  if (n.isImm())
+    return nInit(n.intval());
+  else
+  {
+    number z=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+    z->debug=123456;
+#endif
+    z->z = gmp_numerator( n );
+    if ( n.den() == 1 )
+      z->s = 3;
+    else
+    {
+      z->n = gmp_denominator( n );
+      z->s = 0;
+    }
+    return z;
+  }
+}
+
+CanonicalForm conv_SingPClapP( poly p, ring r )
+{
+  CanonicalForm result = 0;
+  int e, n = r->N;
+  assume( rPar(r)==0);
+
+  while ( p != NULL )
+  {
+    CanonicalForm term;
+    /* does only work for finite fields */
+    if ( getCharacteristic() != 0 )
+    {
+      Off(SW_USE_EZGCD);
+      term = npInt( pGetCoeff( p ) );
+    }
+    else
+    {
+      if ( (int)(pGetCoeff( p )) & 1 )
+      {
+        term = ((int)( pGetCoeff( p ) )>>2);
+      }
+      else
+      {
+        if ( pGetCoeff( p )->s == 3 )
+        {
+          MP_INT dummy;
+          mpz_init_set( &dummy, &(pGetCoeff( p )->z) );
+          term = make_cf( dummy );
+        }
+        else  if ( pGetCoeff( p )->s == 1 )
+        {
+          MP_INT num, den;
+          On(SW_RATIONAL);
+          mpz_init_set( &num, &(pGetCoeff( p )->z) );
+          mpz_init_set( &den, &(pGetCoeff( p )->n) );
+          term = make_cf( num, den, false );
+        }
+        else
+        { // assume s == 0
+          MP_INT num, den;
+          mpz_init_set( &num, &(pGetCoeff( p )->z) );
+          mpz_init_set( &den, &(pGetCoeff( p )->n) );
+          term = make_cf( num, den, true );
+        }
+      }
+    }
+    for ( int i = 1; i <= n; i++ )
+    {
+      if ( (e = p_GetExp( p, i, r )) != 0 )
+         term *= power( Variable( i ), e );
+    }
+    result += term;
+    p = pNext( p );
+  }
+  return result;
+}
+
+poly convClapPSingP ( const CanonicalForm & f )
+{
+//    cerr << " f = " << f << endl;
+  int n = pVariables+1;
+  /* ASSERT( level( f ) <= pVariables, "illegal number of variables" ); */
+  int * exp = new int[n];
+  //for ( int i = 0; i < n; i++ ) exp[i] = 0;
+  memset(exp,0,n*sizeof(int));
+  poly result = NULL;
+  convRecPP( f, exp, result );
+  delete [] exp;
+  return result;
+}
+
+static void convRecPP ( const CanonicalForm & f, int * exp, poly & result )
+{
+  if (f == 0)
+    return;
+  if ( ! f.inCoeffDomain() )
+  {
+    int l = f.level();
+    for ( CFIterator i = f; i.hasTerms(); i++ )
+    {
+      exp[l] = i.exp();
+      convRecPP( i.coeff(), exp, result );
+    }
+    exp[l] = 0;
+  }
+  else
+  {
+    poly term = pInit();
+    pNext( term ) = NULL;
+    for ( int i = 1; i <= pVariables; i++ )
+      pSetExp( term, i, exp[i]);
+    pSetComp(term, 0);
+    if ( getCharacteristic() != 0 )
+    {
+      pGetCoeff( term ) = nInit( f.intval() );
+    }
+    else
+    {
+      if ( f.isImm() )
+        pGetCoeff( term ) = nInit( f.intval() );
+      else
+      {
+        number z=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+        z->debug=123456;
+#endif
+        z->z = gmp_numerator( f );
+        if ( f.den() == 1 )
+          z->s = 3;
+        else
+        {
+          z->n = gmp_denominator( f );
+          z->s = 0;
+        }
+        pGetCoeff( term ) = z;
+      }
+    }
+    pSetm( term );
+    if ( nIsZero(pGetCoeff(term)) )
+    {
+      pDelete(&term);
+    }
+    else
+    {
+      result = pAdd( result, term );
+    }
+  }
+}
+
+poly conv_ClapPSingP ( const CanonicalForm & f, ring r )
+{
+//    cerr << " f = " << f << endl;
+  int n = r->N+1;
+  /* ASSERT( level( f ) <= pVariables, "illegal number of variables" ); */
+  int * exp = new int[n];
+  //for ( int i = 0; i < n; i++ ) exp[i] = 0;
+  memset(exp,0,n*sizeof(int));
+  poly result = NULL;
+  conv_RecPP( f, exp, result, r );
+  delete [] exp;
+  return result;
+}
+
+static void
+conv_RecPP ( const CanonicalForm & f, int * exp, poly & result, ring r )
+{
+  if (f == 0)
+    return;
+  if ( ! f.inCoeffDomain() )
+  {
+    int l = f.level();
+    for ( CFIterator i = f; i.hasTerms(); i++ )
+    {
+      exp[l] = i.exp();
+      conv_RecPP( i.coeff(), exp, result, r );
+    }
+    exp[l] = 0;
+  }
+  else
+  {
+    poly term = p_Init(r);
+    pNext( term ) = NULL;
+    for ( int i = 1; i <= r->N; i++ )
+      p_SetExp( term, i, exp[i], r);
+    if (rRing_has_Comp(r)) p_SetComp(term, 0, r);
+    if ( getCharacteristic() != 0 )
+    {
+      pGetCoeff( term ) = n_Init( f.intval(), r );
+    }
+    else
+    {
+      if ( f.isImm() )
+        pGetCoeff( term ) = n_Init( f.intval(), r );
+      else
+      {
+        number z=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+        z->debug=123456;
+#endif
+        z->z = gmp_numerator( f );
+        if ( f.den() == 1 )
+          z->s = 3;
+        else
+        {
+          z->n = gmp_denominator( f );
+          z->s = 0;
+        }
+        pGetCoeff( term ) = z;
+      }
+    }
+    p_Setm( term, r );
+    if ( n_IsZero(pGetCoeff(term), r) )
+    {
+      p_Delete(&term,r);
+    }
+    else
+    {
+      result = p_Add_q( result, term, r );
+    }
+  }
+}
+
+
+CanonicalForm
+convSingTrClapP( napoly p )
+{
+  CanonicalForm result = 0;
+  int e, n = napVariables;
+
+  while ( p!=NULL)
+  {
+    CanonicalForm term;
+    /* does only work for finite fields */
+    if ( getCharacteristic() != 0 )
+    {
+      Off(SW_USE_EZGCD);
+      term = npInt( napGetCoeff( p ) );
+    }
+    else
+    {
+      On(SW_USE_EZGCD);
+      //if ( (!(int)(napGetCoeff( p )) & 1 )
+      //&&  ( napGetCoeff( p )->s == 0))
+      //  naNormalize( naGetCoeff( p ) );
+      if ( (int)(napGetCoeff( p )) & 1 )
+        term = nlInt( napGetCoeff( p ) );
+      else
+      {
+        if ( napGetCoeff( p )->s == 3 )
+        {
+          MP_INT dummy;
+          mpz_init_set( &dummy, &(napGetCoeff( p )->z) );
+          term = make_cf( dummy );
+        }
+        else  if ( napGetCoeff( p )->s == 1 )
+        {
+          MP_INT num, den;
+          On(SW_RATIONAL);
+          mpz_init_set( &num, &(napGetCoeff( p )->z) );
+          mpz_init_set( &den, &(napGetCoeff( p )->n) );
+          term = make_cf( num, den, false );
+        }
+        else
+        { // assume s == 0
+          MP_INT num, den;
+          On(SW_RATIONAL);
+          mpz_init_set( &num, &(napGetCoeff( p )->z) );
+          mpz_init_set( &den, &(napGetCoeff( p )->n) );
+          term = make_cf( num, den, true );
+        }
+      }
+    }
+    for ( int i = 1; i <= n; i++ )
+    {
+      if ( (e = napGetExp( p, i )) != 0 )
+        term *= power( Variable( i ), e );
+    }
+    result += term;
+    p = napNext( p );
+  }
+  return result;
+}
+
+napoly
+convClapPSingTr ( const CanonicalForm & f )
+{
+//    cerr << " f = " << f << endl;
+  int n = napVariables+1;
+  /* ASSERT( level( f ) <= napVariables, "illegal number of variables" ); */
+  int * exp = new int[n];
+  // for ( int i = 0; i < n; i++ ) exp[i] = 0;
+  memset(exp,0,n*sizeof(int));
+  napoly result = NULL;
+  convRecPTr( f, exp, result );
+  delete [] exp;
+  return result;
+}
+
+static void
+convRecPTr ( const CanonicalForm & f, int * exp, napoly & result )
+{
+  if (f == 0)
+    return;
+  if ( ! f.inCoeffDomain() )
+  {
+    int l = f.level();
+    for ( CFIterator i = f; i.hasTerms(); i++ )
+    {
+        exp[l] = i.exp();
+        convRecPTr( i.coeff(), exp, result );
+    }
+    exp[l] = 0;
+  }
+  else
+  {
+    napoly term = napNew();
+    // napNext( term ) = NULL; //already done by napNew
+    for ( int i = 1; i <= napVariables; i++ )
+      napSetExp( term, i , exp[i]);
+    if ( getCharacteristic() != 0 )
+    {
+      napGetCoeff( term ) = npInit( f.intval() );
+    }
+    else
+    {
+      if ( f.isImm() )
+        napGetCoeff( term ) = nlInit( f.intval() );
+      else
+      {
+        number z=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+        z->debug=123456;
+#endif
+        z->z = gmp_numerator( f );
+        if ( f.den() == 1 )
+        {
+          z->s = 3;
+        }
+        else
+        {
+          z->n = gmp_denominator( f );
+          if (mpz_cmp_si(&z->n,(long)1)==0)
+          {
+            mpz_clear(&z->n);
+            z->s=3;
+          }
+          else
+          {
+            z->s = 0;
+          }
+          nacNormalize(z);
+        }
+        napGetCoeff( term ) = z;
+      }
+    }
+    result = napAdd( result, term );
+  }
+}
+
+CanonicalForm convSingAPClapAP ( poly p , const Variable & a)
+{
+  CanonicalForm result = 0;
+  int e, n = pVariables;
+  int off=rPar(currRing);
+
+  On(SW_RATIONAL);
+  while ( p!=NULL)
+  {
+    CanonicalForm term=convSingAClapA(((lnumber)pGetCoeff(p))->z,a);
+    for ( int i = 1; i <= n; i++ )
+    {
+      if ( (e = pGetExp( p, i )) != 0 )
+        term *= power( Variable( i + off), e );
+    }
+    result += term;
+    p = pNext( p );
+  }
+  return result;
+}
+
+poly convClapAPSingAP ( const CanonicalForm & f )
+{
+  int n = pVariables+1+1/*rPar(currRing)*/;
+  int * exp = new int[n];
+  // for ( int i = 0; i < n; i++ ) exp[i] = 0;
+  memset(exp,0,n*sizeof(int));
+  poly result = NULL;
+  convRecAP( f, exp, result );
+  delete [] exp;
+  return result;
+}
+
+static void
+convRecAP ( const CanonicalForm & f, int * exp, poly & result )
+{
+  if (f == 0)
+    return;
+  int off=rPar(currRing);
+  if ( ! f.inCoeffDomain() )
+  {
+    int l = f.level();
+    for ( CFIterator i = f; i.hasTerms(); i++ )
+    {
+      exp[l] = i.exp();
+      convRecAP( i.coeff(), exp, result );
+    }
+    exp[l] = 0;
+  }
+  else
+  {
+    napoly z=(napoly)convClapASingA( f );
+    if (z!=NULL)
+    {
+      poly term = pInit();
+      pNext( term ) = NULL;
+      int i;
+      for ( i = 1; i <= pVariables; i++ )
+        pSetExp( term, i , exp[i+off]);
+      pSetComp(term, 0);
+      for ( i = 1; i <= off; i++ )
+        //z->e[i-1]+=exp[i];
+	napAddExp(z,i,exp[i]);
+      pGetCoeff(term)=(number)omAlloc0Bin(rnumber_bin);
+      ((lnumber)pGetCoeff(term))->z=z;
+      pSetm( term );
+      result = pAdd( result, term );
+    }
+  }
+}
+
+CanonicalForm convSingAClapA ( napoly p , const Variable & a )
+{
+  CanonicalForm result = 0;
+  int e;
+
+  while ( p!=NULL )
+  {
+    CanonicalForm term;
+    /* does only work for finite fields:Z/p */
+    if ( rField_is_Zp_a() )
+    {
+      Off(SW_USE_EZGCD);
+      term = npInt( napGetCoeff( p ) );
+    }
+    else
+    {
+      On(SW_USE_EZGCD);
+      //if ( (!(int)(napGetCoeff( p )) & 1 )
+      //&&  ( napGetCoeff( p )->s == 0))
+      //  naNormalize( naGetCoeff( p ) );
+      if ( (int)(napGetCoeff( p )) & SR_INT )
+        term = nlInt( napGetCoeff( p ) );
+        //term = SR_TO_INT(napGetCoeff( p )) ;
+      else
+      {
+        if ( napGetCoeff( p )->s == 3 )
+        {
+          MP_INT dummy;
+          mpz_init_set( &dummy, &(napGetCoeff( p )->z) );
+          term = make_cf( dummy );
+        }
+        else  if ( napGetCoeff( p )->s == 1 )
+        {
+          MP_INT num, den;
+          On(SW_RATIONAL);
+          mpz_init_set( &num, &(napGetCoeff( p )->z) );
+          mpz_init_set( &den, &(napGetCoeff( p )->n) );
+          term = make_cf( num, den, false );
+        }
+        else
+        { // assume s == 0
+          MP_INT num, den;
+          On(SW_RATIONAL);
+          mpz_init_set( &num, &(napGetCoeff( p )->z) );
+          mpz_init_set( &den, &(napGetCoeff( p )->n) );
+          term = make_cf( num, den, true );
+        }
+      }
+    }
+    if ( (e = napGetExp( p, 1 )) != 0 )
+      term *= power( a , e );
+    result += term;
+    p = napNext( p );
+  }
+  return result;
+}
+
+static number convClapNSingAN( const CanonicalForm &f)
+{
+  if ((getCharacteristic() != 0) || ( f.isImm() ))
+    return nacInit( f.intval() );
+  else
+  {
+    number z=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+    z->debug=123456;
+#endif
+    z->z = gmp_numerator( f );
+    if ( f.den() == 1 )
+    {
+      z->s = 3;
+    }
+    else
+    {
+      z->n = gmp_denominator( f );
+      z->s = 0;
+    }
+    #ifdef LDEBUG
+    nlDBTest(z,__FILE__,__LINE__);
+    #endif
+    return z;
+  }
+}
+
+napoly convClapASingA ( const CanonicalForm & f )
+{
+  napoly a=NULL;
+  napoly t;
+  for( CFIterator i=f; i.hasTerms(); i++)
+  {
+    t=napNew();
+    // napNext( t ) = NULL; //already done by napNew
+    napGetCoeff(t)=convClapNSingAN( i.coeff() );
+    if (nacIsZero(napGetCoeff(t)))
+    {
+      napDelete(&t);
+    }
+    else
+    {
+      napSetExp(t,1,i.exp());
+      a=napAdd(a,t);
+    }
+  }
+  return a;
+}
+
+CanonicalForm convSingTrPClapP ( poly p )
+{
+  CanonicalForm result = 0;
+  int e, n = pVariables;
+  int offs = rPar(currRing);
+
+  while ( p!=NULL )
+  {
+    nNormalize(pGetCoeff(p));
+    CanonicalForm term=convSingTrClapP(((lnumber)pGetCoeff(p))->z);
+    for ( int i = 1; i <= n; i++ )
+    {
+      if ( (e = pGetExp( p, i )) != 0 )
+        term = term * power( Variable( i + offs ), e );
+    }
+    result += term;
+    p = pNext( p );
+  }
+  return result;
+}
+
+poly convClapPSingTrP ( const CanonicalForm & f )
+{
+  int n = pVariables+1;
+  int * exp = new int[n];
+  // for ( int i = 0; i < n; i++ ) exp[i] = 0;
+  memset(exp,0,n*sizeof(int));
+  poly result = NULL;
+  convRecTrP( f, exp, result , rPar(currRing) );
+  delete [] exp;
+  return result;
+}
+
+static void
+convRecTrP ( const CanonicalForm & f, int * exp, poly & result , int offs)
+{
+  if (f == 0)
+    return;
+  if ( f.level() > offs )
+  {
+    int l = f.level();
+    for ( CFIterator i = f; i.hasTerms(); i++ )
+    {
+      exp[l-offs] = i.exp();
+      convRecTrP( i.coeff(), exp, result, offs );
+    }
+    exp[l-offs] = 0;
+  }
+  else
+  {
+    poly term = pInit();
+    pNext( term ) = NULL;
+    for ( int i = 1; i <= pVariables; i++ )
+      pSetExp( term, i ,exp[i]);
+    pSetComp(term, 0);
+    pGetCoeff(term)=(number)omAlloc0Bin(rnumber_bin);
+    ((lnumber)pGetCoeff(term))->z=convClapPSingTr( f );
+    pSetm( term );
+    result = pAdd( result, term );
+  }
+}
+
+#if 0
+CanonicalForm
+convSingGFClapGF( poly p )
+{
+  CanonicalForm result = 0;
+  int e, n = pVariables;
+
+  while ( p != NULL )
+  {
+    CanonicalForm term;
+    term = make_cf_from_gf( pGetCoeff( p ) );
+    for ( int i = 1; i <= n; i++ )
+    {
+      if ( (e = pGetExp( p, i )) != 0 )
+         term *= power( Variable( i ), e );
+    }
+    result += term;
+    p = pNext( p );
+  }
+  return result;
+}
+
+poly
+convClapGFSingGF ( const CanonicalForm & f )
+{
+//    cerr << " f = " << f << endl;
+  int n = pVariables+1;
+  /* ASSERT( level( f ) <= pVariables, "illegal number of variables" ); */
+  int * exp = new int[n];
+  //for ( int i = 0; i < n; i++ ) exp[i] = 0;
+  memset(exp,0,n*sizeof(int));
+  poly result = NULL;
+  convRecGFGF( f, exp, result );
+  delete [] exp;
+  return result;
+}
+
+static void
+convRecGFGF ( const CanonicalForm & f, int * exp, poly & result )
+{
+  if (f == 0)
+    return;
+  if ( ! f.inCoeffDomain() )
+  {
+    int l = f.level();
+    for ( CFIterator i = f; i.hasTerms(); i++ )
+    {
+      exp[l] = i.exp();
+      convRecGFGF( i.coeff(), exp, result );
+    }
+    exp[l] = 0;
+  }
+  else
+  {
+    poly term = pInit();
+    pNext( term ) = NULL;
+    for ( int i = 1; i <= pVariables; i++ )
+      pSetExp( term, i, exp[i]);
+    pSetComp(term, 0);
+    pGetCoeff( term ) = (number) gf_value (f);
+    pSetm( term );
+    result = pAdd( result, term );
+  }
+}
+#endif
+
+int convClapISingI( const CanonicalForm & f)
+{
+  if (!f.isImm()) WerrorS("int overflow in det");
+  return f.intval();
+}
+#endif
Index: kernel/clapconv.h
===================================================================
--- kernel/clapconv.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/clapconv.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,45 @@
+// emacs edit mode for this file is -*- C++ -*-
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+// $Id: clapconv.h,v 1.1.1.1 2003-10-06 12:15:50 Singular Exp $
+/*
+* ABSTRACT: convert data between Singular and factory
+*/
+
+
+#ifndef INCL_SINGCONV_H
+#define INCL_SINGCONV_H
+
+#include "structs.h"
+#include "longalg.h"
+#include <factory.h>
+
+napoly convClapPSingTr ( const CanonicalForm & f );
+CanonicalForm convSingTrClapP( napoly p );
+
+poly convClapPSingP ( const CanonicalForm & f );
+#define  convSingPClapP(p) conv_SingPClapP(p,currRing)
+
+poly conv_ClapPSingP ( const CanonicalForm & f, ring r );
+CanonicalForm conv_SingPClapP( poly p, ring r );
+
+CanonicalForm convSingAPClapAP ( poly p , const Variable & a );
+poly convClapAPSingAP ( const CanonicalForm & f );
+
+CanonicalForm convSingGFClapGF ( poly p );
+poly convClapGFSingGF ( const CanonicalForm & f );
+
+CanonicalForm convSingAClapA ( napoly p , const Variable & a );
+napoly convClapASingA ( const CanonicalForm & f );
+
+CanonicalForm convSingTrPClapP ( poly p );
+poly convClapPSingTrP ( const CanonicalForm & f );
+
+CanonicalForm convSingNClapN( number n );
+number convClapNSingN( const CanonicalForm & n);
+
+
+// CanonicalForm convSingIClapI( int i);a <- by constructor of CanonicalForm
+int convClapISingI( const CanonicalForm & f);
+#endif /* INCL_SINGCONV_H */
Index: kernel/clapsing.cc
===================================================================
--- kernel/clapsing.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/clapsing.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1414 @@
+// emacs edit mode for this file is -*- C++ -*-
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+// $Id: clapsing.cc,v 1.1.1.1 2003-10-06 12:15:50 Singular Exp $
+/*
+* ABSTRACT: interface between Singular and factory
+*/
+
+#include "mod2.h"
+#include "omalloc.h"
+#ifdef HAVE_FACTORY
+#define SI_DONT_HAVE_GLOBAL_VARS
+#include "structs.h"
+#include "clapsing.h"
+#include "numbers.h"
+#include "ring.h"
+#include <factory.h>
+#include "clapconv.h"
+#ifdef HAVE_LIBFAC_P
+#include <factor.h>
+//CanonicalForm algcd(const CanonicalForm & F, const CanonicalForm & g, const CFList & as, const Varlist & order);
+CanonicalForm alg_gcd(const CanonicalForm &, const CanonicalForm &, const CFList &);
+#endif
+#include "ring.h"
+
+//
+// FACTORY_GCD_TEST: use new gcd instead of old one.  Does not work
+//   without new gcd-implementation which is not publicly available.
+//
+// FACTORY_GCD_STAT: print statistics on polynomials.  Works only
+//   with the file `gcd_stat.cc' and `gcd_stat.h which may be found
+//   in the repository, module `factory-devel'.
+//   Overall statistics may printed using `system("gcdstat");'.
+//
+// FACTORY_GCD_TIMING: accumulate time used for gcd calculations.
+//   Time may be printed (and reset) with `system("gcdtime");'.
+//   For this define, `timing.h' from the factory source directory
+//   has to be copied to the Singular source directory.
+//   Note: for better readability, the macros `TIMING_START()' and
+//   `TIMING_END()' are used in any case.  However, they expand to
+//   nothing if `FACTORY_GCD_TIMING' is off.
+//
+// FACTORY_GCD_DEBOUT: print polynomials involved in gcd calculations.
+//   The polynomials are printed by means of the macros
+//   `FACTORY_*OUT_POLY' which are defined to be empty if
+//   `FACTORY_GCD_DEBOUT' is off.
+//
+// FACTORY_GCD_DEBOUT_PATTERN: print degree patterns of polynomials
+//   involved in gcd calculations.
+//   The patterns are printed by means of the macros
+//   `FACTORY_*OUT_PAT' which are defined to be empty if
+//   `FACTORY_GCD_DEBOUT_PATTERN' is off.
+//
+//   A degree pattern looks like this:
+//
+//   totDeg  size    deg(v1) deg(v2) ...
+//
+//   where "totDeg" means total degree, "size" the number of terms,
+//   and "deg(vi)" is the degree with respect to variable i.
+//   In univariate case, the "deg(vi)" are missing.  For this feature
+//   you need the files `gcd_stat.cc' and `gcd_stat.h'.
+//
+//
+// And here is what the functions print if `FACTORY_GCD_DEBOUT' (1),
+// `FACTORY_GCD_STAT' (2), or `FACTORY_GCD_DEBOUT_PATTERN' (3) is on:
+//
+// sinclap_divide_content:
+// (1) G = <firstCoeff>
+// (3) G#= <firstCoeff, pattern>
+// (1) h = <nextCoeff>
+// (3) h#= <nextCoeff, pattern>
+// (2) gcnt: <statistics on gcd as explained above>
+// (1) g = <intermediateResult>
+// (3) g#= <intermediateResult, pattern>
+// (1) h = <nextCoeff>
+// (3) h#= <nextCoeff, pattern>
+// (2) gcnt: <statistics on gcd as explained above>
+//  ...
+// (1) h = <lastCoeff>
+// (3) h#= <lastCoeff, pattern>
+// (1) g = <finalResult>
+// (3) g#= <finalResult, pattern>
+// (2) gcnt: <statistics on gcd as explained above>
+// (2) cont: <statistics on content as explained above>
+//
+// singclap_alglcm:
+// (1) f = <inputPolyF>
+// (3) f#= <inputPolyF, pattern>
+// (1) g = <inputPolyG>
+// (3) g#= <inputPolyG, pattern>
+// (1) d = <its gcd>
+// (3) d#= <its gcd, pattern>
+// (2) alcm: <statistics as explained above>
+//
+// singclap_algdividecontent:
+// (1) f = <inputPolyF>
+// (3) f#= <inputPolyF, pattern>
+// (1) g = <inputPolyG>
+// (3) g#= <inputPolyG, pattern>
+// (1) d = <its gcd>
+// (3) d#= <its gcd, pattern>
+// (2) acnt: <statistics as explained above>
+//
+
+#ifdef FACTORY_GCD_STAT
+#include "gcd_stat.h"
+#define FACTORY_GCDSTAT( tag, f, g, d ) \
+  printGcdStat( tag, f, g, d )
+#define FACTORY_CONTSTAT( tag, f ) \
+  printContStat( tag, f )
+#else
+#define FACTORY_GCDSTAT( tag, f, g, d )
+#define FACTORY_CONTSTAT( tag, f )
+#endif
+
+#ifdef FACTORY_GCD_TIMING
+#define TIMING
+#include "timing.h"
+TIMING_DEFINE_PRINT( contentTimer );
+TIMING_DEFINE_PRINT( algContentTimer );
+TIMING_DEFINE_PRINT( algLcmTimer );
+#else
+#define TIMING_START( timer )
+#define TIMING_END( timer )
+#endif
+
+#ifdef FACTORY_GCD_DEBOUT
+#include "longalg.h"
+#include "febase.h"
+// napoly f
+#define FACTORY_ALGOUT_POLY( tag, f ) \
+  StringSetS( tag ); \
+  napWrite( f ); \
+  pRINtS(StringAppendS("\n"));
+// CanonicalForm f, represents transcendent extension
+#define FACTORY_CFTROUT_POLY( tag, f ) \
+  { \
+    napoly F=convClapPSingTr( f ); \
+    StringSetS( tag ); \
+    napWrite( F ); \
+    PrintS(StringAppendS("\n")); \
+    napDelete(&F); \
+  }
+// CanonicalForm f, represents algebraic extension
+#define FACTORY_CFAOUT_POLY( tag, f ) \
+  { \
+    napoly F=convClapASingA( f ); \
+    StringSetS( tag ); \
+    napWrite( F ); \
+    PrintS(StringAppendS("\n")); \
+    napDelete(&F); \
+  }
+#else /* ! FACTORY_GCD_DEBOUT */
+#define FACTORY_ALGOUT_POLY( tag, f )
+#define FACTORY_CFTROUT_POLY( tag, f )
+#define FACTORY_CFAOUT_POLY( tag, f )
+#endif /* ! FACTORY_GCD_DEBOUT */
+
+#ifdef FACTORY_GCD_DEBOUT_PATTERN
+// napoly f
+#define FACTORY_ALGOUT_PAT( tag, f ) \
+  if (currRing->minpoly!=NULL) \
+  { \
+    CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z); \
+    Variable a=rootOf(mipo); \
+    printPolyPattern( tag, convSingAClapA( f,a ), rPar( currRing ) ); \
+  } \
+  else \
+  { \
+    printPolyPattern( tag, convSingTrClapP( f ), rPar( currRing ) ); \
+  }
+// CanonicalForm f, represents transcendent extension
+#define FACTORY_CFTROUT_PAT( tag, f ) printPolyPattern( tag, f, rPar( currRing ) )
+// CanonicalForm f, represents algebraic extension
+#define FACTORY_CFAOUT_PAT( tag, f ) printPolyPattern( tag, f, rPar( currRing ) )
+#else /* ! FACTORY_GCD_DEBOUT_PATTERN */
+#define FACTORY_ALGOUT_PAT( tag, f )
+#define FACTORY_CFTROUT_PAT( tag, f )
+#define FACTORY_CFAOUT_PAT( tag, f )
+#endif /* ! FACTORY_GCD_DEBOUT_PATTERN */
+
+// these macors combine both print macros
+#define FACTORY_ALGOUT( tag, f ) \
+  FACTORY_ALGOUT_POLY( tag " = ", f ); \
+  FACTORY_ALGOUT_PAT( tag "#= ", f )
+#define FACTORY_CFTROUT( tag, f ) \
+  FACTORY_CFTROUT_POLY( tag " = ", f ); \
+  FACTORY_CFTROUT_PAT( tag "#= ", f )
+#define FACTORY_CFAOUT( tag, f ) \
+  FACTORY_CFAOUT_POLY( tag " = ", f ); \
+  FACTORY_CFAOUT_PAT( tag "#= ", f )
+
+
+
+
+
+poly singclap_gcd ( poly f, poly g )
+{
+  poly res=NULL;
+
+  if (f!=NULL) pCleardenom(f);
+  if (g!=NULL) pCleardenom(g);
+  else         return pCopy(f); // g==0 => gcd=f (but do a pCleardenom)
+  if (f==NULL) return pCopy(g); // f==0 => gcd=g (but do a pCleardenom)
+
+  if (pIsConstant(f) || pIsConstant(g)) return pOne();
+
+  // for now there is only the possibility to handle polynomials over
+  // Q and Fp ...
+  if (( nGetChar() == 0 || nGetChar() > 1 )
+  && (currRing->parameter==NULL))
+  {
+    setCharacteristic( nGetChar() );
+    CanonicalForm F( convSingPClapP( f ) ), G( convSingPClapP( g ) );
+    res=convClapPSingP( gcd( F, G ) );
+    Off(SW_RATIONAL);
+  }
+  // and over Q(a) / Fp(a)
+  else if (( nGetChar()==1 ) /* Q(a) */
+  || (nGetChar() <-1))       /* Fp(a) */
+  {
+    if (nGetChar()==1) setCharacteristic( 0 );
+    else               setCharacteristic( -nGetChar() );
+    if (currRing->minpoly!=NULL)
+    {
+      if ( nGetChar()==1 ) /* Q(a) */
+      {
+      //  WerrorS( feNotImplemented );
+        CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
+        //Varlist ord;
+        //ord.append(mipo.mvar());
+        CFList as(mipo);
+        Variable a=rootOf(mipo);
+        //CanonicalForm F( convSingAPClapAP( f,a ) ), G( convSingAPClapAP( g,a ) );
+        CanonicalForm F( convSingTrPClapP(f) ), G( convSingTrPClapP(g) );
+        //res= convClapAPSingAP( algcd( F, G, as, ord) );
+        //res= convClapAPSingAP( alg_gcd( F, G, as) );
+        res= convClapAPSingAP( alg_gcd( F, G, as) );
+      }
+      else
+      {
+        CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
+        Variable a=rootOf(mipo);
+        CanonicalForm F( convSingAPClapAP( f,a ) ), G( convSingAPClapAP( g,a ) );
+        res= convClapAPSingAP( gcd( F, G ) );
+      }
+    }
+    else
+    {
+      CanonicalForm F( convSingTrPClapP( f ) ), G( convSingTrPClapP( g ) );
+      res= convClapPSingTrP( gcd( F, G ) );
+    }
+    Off(SW_RATIONAL);
+  }
+  #if 0
+  else if (( nGetChar()>1 )&&(currRing->parameter!=NULL)) /* GF(q) */
+  {
+    int p=rChar(currRing);
+    int n=2;
+    int t=p*p;
+    while (t!=nChar) { t*=p;n++; }
+    setCharacteristic(p,n,'a');
+    CanonicalForm F( convSingGFClapGF( f ) ), G( convSingGFClapGF( g ) );
+    res= convClapGFSingGF( gcd( F, G ) );
+  }
+  #endif
+  else
+    WerrorS( feNotImplemented );
+
+  pDelete(&f);
+  pDelete(&g);
+  pTest(res);
+  return res;
+}
+
+poly singclap_resultant ( poly f, poly g , poly x)
+{
+  int i=pIsPurePower(x);
+  if (i==0)
+  {
+    WerrorS("3rd argument must be a ring variable");
+    return NULL;
+  }
+  if ((f==NULL) || (g==NULL))
+    return NULL;
+  // for now there is only the possibility to handle polynomials over
+  // Q and Fp ...
+  if (( nGetChar() == 0 || nGetChar() > 1 )
+  && (currRing->parameter==NULL))
+  {
+    Variable X(i);
+    setCharacteristic( nGetChar() );
+    CanonicalForm F( convSingPClapP( f ) ), G( convSingPClapP( g ) );
+    poly res=convClapPSingP( resultant( F, G, X ) );
+    Off(SW_RATIONAL);
+    return res;
+  }
+  // and over Q(a) / Fp(a)
+  else if (( nGetChar()==1 ) /* Q(a) */
+  || (nGetChar() <-1))       /* Fp(a) */
+  {
+    if (nGetChar()==1) setCharacteristic( 0 );
+    else               setCharacteristic( -nGetChar() );
+    poly res;
+    if (currRing->minpoly!=NULL)
+    {
+      Variable X(i);
+      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
+      Variable a=rootOf(mipo);
+      CanonicalForm F( convSingAPClapAP( f,a ) ), G( convSingAPClapAP( g,a ) );
+      res= convClapAPSingAP( resultant( F, G, X ) );
+    }
+    else
+    {
+      Variable X(i+rPar(currRing));
+      CanonicalForm F( convSingTrPClapP( f ) ), G( convSingTrPClapP( g ) );
+      res= convClapPSingTrP( resultant( F, G, X ) );
+    }
+    Off(SW_RATIONAL);
+    return res;
+  }
+  else
+    WerrorS( feNotImplemented );
+  return NULL;
+}
+//poly singclap_resultant ( poly f, poly g , poly x)
+//{
+//  int i=pVar(x);
+//  if (i==0)
+//  {
+//    WerrorS("ringvar expected");
+//    return NULL;
+//  }
+//  ideal I=idInit(1,1);
+//
+//  // get the coeffs von f wrt. x:
+//  I->m[0]=pCopy(f);
+//  matrix ffi=mpCoeffs(I,i);
+//  ffi->rank=1;
+//  ffi->ncols=ffi->nrows;
+//  ffi->nrows=1;
+//  ideal fi=(ideal)ffi;
+//
+//  // get the coeffs von g wrt. x:
+//  I->m[0]=pCopy(g);
+//  matrix ggi=mpCoeffs(I,i);
+//  ggi->rank=1;
+//  ggi->ncols=ggi->nrows;
+//  ggi->nrows=1;
+//  ideal gi=(ideal)ggi;
+//
+//  // contruct the matrix:
+//  int fn=IDELEMS(fi); //= deg(f,x)+1
+//  int gn=IDELEMS(gi); //= deg(g,x)+1
+//  matrix m=mpNew(fn+gn-2,fn+gn-2);
+//  if(m==NULL)
+//  {
+//    return NULL;
+//  }
+//
+//  // enter the coeffs into m:
+//  int j;
+//  for(i=0;i<gn-1;i++)
+//  {
+//    for(j=0;j<fn;j++)
+//    {
+//      MATELEM(m,i+1,fn-j+i)=pCopy(fi->m[j]);
+//    }
+//  }
+//  for(i=0;i<fn-1;i++)
+//  {
+//    for(j=0;j<gn;j++)
+//    {
+//      MATELEM(m,gn+i,gn-j+i)=pCopy(gi->m[j]);
+//    }
+//  }
+//
+//  poly r=mpDet(m);
+//
+//  idDelete(&fi);
+//  idDelete(&gi);
+//  idDelete((ideal *)&m);
+//  return r;
+//}
+
+BOOLEAN singclap_extgcd ( poly f, poly g, poly &res, poly &pa, poly &pb )
+{
+  // for now there is only the possibility to handle univariate
+  // polynomials over
+  // Q and Fp ...
+  res=NULL;pa=NULL;pb=NULL;
+  On(SW_SYMMETRIC_FF);
+  if (( nGetChar() == 0 || nGetChar() > 1 )
+  && (currRing->parameter==NULL))
+  {
+    setCharacteristic( nGetChar() );
+    CanonicalForm F( convSingPClapP( f ) ), G( convSingPClapP( g ) );
+    if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
+    {
+      Off(SW_RATIONAL);
+      WerrorS("not univariate");
+      return TRUE;
+    }
+    CanonicalForm Fa,Gb;
+    On(SW_RATIONAL);
+    res=convClapPSingP( extgcd( F, G, Fa, Gb ) );
+    pa=convClapPSingP(Fa);
+    pb=convClapPSingP(Gb);
+    Off(SW_RATIONAL);
+  }
+  // and over Q(a) / Fp(a)
+  else if (( nGetChar()==1 ) /* Q(a) */
+  || (nGetChar() <-1))       /* Fp(a) */
+  {
+    if (nGetChar()==1) setCharacteristic( 0 );
+    else               setCharacteristic( -nGetChar() );
+    CanonicalForm Fa,Gb;
+    if (currRing->minpoly!=NULL)
+    {
+      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
+      Variable a=rootOf(mipo);
+      CanonicalForm F( convSingAPClapAP( f,a ) ), G( convSingAPClapAP( g,a ) );
+      if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
+      {
+        WerrorS("not univariate");
+        return TRUE;
+      }
+      res= convClapAPSingAP( extgcd( F, G, Fa, Gb ) );
+      pa=convClapAPSingAP(Fa);
+      pb=convClapAPSingAP(Gb);
+    }
+    else
+    {
+      CanonicalForm F( convSingTrPClapP( f ) ), G( convSingTrPClapP( g ) );
+      if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
+      {
+        Off(SW_RATIONAL);
+        WerrorS("not univariate");
+        return TRUE;
+      }
+      res= convClapPSingTrP( extgcd( F, G, Fa, Gb ) );
+      pa=convClapPSingTrP(Fa);
+      pb=convClapPSingTrP(Gb);
+    }
+    Off(SW_RATIONAL);
+  }
+  else
+  {
+    WerrorS( feNotImplemented );
+    return TRUE;
+  }
+  return FALSE;
+}
+
+poly singclap_pdivide ( poly f, poly g )
+{
+  // for now there is only the possibility to handle polynomials over
+  // Q and Fp ...
+  poly res=NULL;
+  On(SW_RATIONAL);
+  if (( nGetChar() == 0 || nGetChar() > 1 )
+  && (currRing->parameter==NULL))
+  {
+    setCharacteristic( nGetChar() );
+    CanonicalForm F( convSingPClapP( f ) ), G( convSingPClapP( g ) );
+    res = convClapPSingP( F / G );
+  }
+  // and over Q(a) / Fp(a)
+  else if (( nGetChar()==1 ) /* Q(a) */
+  || (nGetChar() <-1))       /* Fp(a) */
+  {
+    if (nGetChar()==1) setCharacteristic( 0 );
+    else               setCharacteristic( -nGetChar() );
+    if (currRing->minpoly!=NULL)
+    {
+      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
+      Variable a=rootOf(mipo);
+      CanonicalForm F( convSingAPClapAP( f,a ) ), G( convSingAPClapAP( g,a ) );
+      res= convClapAPSingAP(  F / G  );
+    }
+    else
+    {
+      CanonicalForm F( convSingTrPClapP( f ) ), G( convSingTrPClapP( g ) );
+      res= convClapPSingTrP(  F / G  );
+    }
+  }
+  else
+    WerrorS( feNotImplemented );
+  Off(SW_RATIONAL);
+  return res;
+}
+
+void singclap_divide_content ( poly f )
+{
+  if ( f==NULL )
+  {
+    return;
+  }
+  else  if ( pNext( f ) == NULL )
+  {
+    pSetCoeff( f, nInit( 1 ) );
+    return;
+  }
+  else
+  {
+    if ( nGetChar() == 1 )
+      setCharacteristic( 0 );
+    else  if ( nGetChar() == -1 )
+      return; /* not implemented for R */
+    else  if ( nGetChar() < 0 )
+      setCharacteristic( -nGetChar() );
+    else if (currRing->parameter==NULL) /* not GF(q) */
+      setCharacteristic( nGetChar() );
+    else
+      return; /* not implemented*/
+
+    CFList L;
+    CanonicalForm g, h;
+    poly p = pNext(f);
+
+    // first attemp: find 2 smallest g:
+
+    number g1=pGetCoeff(f);
+    number g2=pGetCoeff(p); // p==pNext(f);
+    pIter(p);
+    int sz1=nSize(g1);
+    int sz2=nSize(g2);
+    if (sz1>sz2)
+    {
+      number gg=g1;
+      g1=g2; g2=gg;
+      int sz=sz1;
+      sz1=sz2; sz2=sz;
+    }
+    while (p!=NULL)
+    {
+      int n_sz=nSize(pGetCoeff(p));
+      if (n_sz<sz1)
+      {
+        sz2=sz1;
+        g2=g1;
+        g1=pGetCoeff(p);
+        sz1=n_sz;
+        if (sz1<=3) break;
+      }
+      else if(n_sz<sz2)
+      {
+        sz2=n_sz;
+        g2=pGetCoeff(p);
+        sz2=n_sz;
+      }
+      pIter(p);
+    }
+    FACTORY_ALGOUT( "G", ((lnumber)g1)->z );
+    g = convSingTrClapP( ((lnumber)g1)->z );
+    g = gcd( g, convSingTrClapP( ((lnumber)g2)->z ));
+
+    // second run: gcd's
+
+    p = f;
+    TIMING_START( contentTimer );
+    while ( (p != NULL) && (g != 1)  && ( g != 0))
+    {
+      FACTORY_ALGOUT( "h", (((lnumber)pGetCoeff(p))->z) );
+      h = convSingTrClapP( ((lnumber)pGetCoeff(p))->z );
+      pIter( p );
+#ifdef FACTORY_GCD_STAT
+      // save g
+      CanonicalForm gOld = g;
+#endif
+
+#ifdef FACTORY_GCD_TEST
+      g = CFPrimitiveGcdUtil::gcd( g, h );
+#else
+      g = gcd( g, h );
+#endif
+
+      FACTORY_GCDSTAT( "gcnt:", gOld, h, g );
+      FACTORY_CFTROUT( "g", g );
+      L.append( h );
+    }
+    TIMING_END( contentTimer );
+    FACTORY_CONTSTAT( "cont:", g );
+    if (( g == 1 ) || (g == 0))
+    {
+      // pTest(f);
+      return;
+    }
+    else
+    {
+      CFListIterator i;
+      for ( i = L, p = f; i.hasItem(); i++, p=pNext(p) )
+      {
+        lnumber c=(lnumber)pGetCoeff(p);
+        napDelete(&c->z);
+        c->z=convClapPSingTr( i.getItem() / g );
+        //nTest((number)c);
+        //#ifdef LDEBUG
+        //number cn=(number)c;
+        //StringSetS(""); nWrite(nt); StringAppend(" ==> ");
+        //nWrite(cn);PrintS(StringAppend("\n"));
+        //#endif
+      }
+    }
+    // pTest(f);
+  }
+}
+
+static int primepower(int c)
+{
+  int p=1;
+  int cc=c;
+  while(cc!= rInternalChar(currRing)) { cc*=c; p++; }
+  return p;
+}
+
+ideal singclap_factorize ( poly f, intvec ** v , int with_exps)
+{
+  // with_exps: 3,1 return only true factors, no exponents
+  //            2 return true factors and exponents
+  //            0 return coeff, factors and exponents
+
+
+  ideal res=NULL;
+
+  // handle factorize(0) =========================================
+  if (f==NULL)
+  {
+    res=idInit(1,1);
+    if (with_exps!=1)
+    {
+      (*v)=new intvec(1);
+      (**v)[0]=1;
+    }
+    return res;
+  }
+  // handle factorize(mon) =========================================
+  if (pNext(f)==NULL)
+  {
+    int i=0;
+    int n=0;
+    int e;
+    for(i=pVariables;i>0;i--) if(pGetExp(f,i)!=0) n++;
+    if (with_exps==0) n++; // with coeff
+    res=idInit(si_max(n,1),1);
+    switch(with_exps)
+    {
+      case 0: // with coef & exp.
+        res->m[0]=pOne();
+        pSetCoeff(res->m[0],nCopy(pGetCoeff(f)));
+        // no break
+      case 2: // with exp.
+        (*v)=new intvec(si_max(n,1));
+        (**v)[0]=1;
+        // no break
+      case 1: ;
+      #ifdef TEST
+      default: ;
+      #endif
+    }
+    if (n==0)
+    {
+      res->m[0]=pOne();
+      // (**v)[0]=1; is already done
+      return res;
+    }
+    for(i=pVariables;i>0;i--)
+    {
+      e=pGetExp(f,i);
+      if(e!=0)
+      {
+        n--;
+        poly p=pOne();
+        pSetExp(p,i,1);
+        pSetm(p);
+        res->m[n]=p;
+        if (with_exps!=1) (**v)[n]=e;
+      }
+    }
+    return res;
+  }
+  //PrintS("S:");pWrite(f);PrintLn();
+  // use factory/liffac in general ==============================
+  Off(SW_RATIONAL);
+  On(SW_SYMMETRIC_FF);
+  On(SW_USE_NTL);
+  #ifdef HAVE_NTL
+  extern int prime_number;
+  if(rField_is_Q()) prime_number=0;
+  #endif
+  CFFList L;
+  number N=NULL;
+  number NN=NULL;
+  number old_lead_coeff=nCopy(pGetCoeff(f));
+
+  if (rField_is_Q() || rField_is_Zp())
+  {
+    setCharacteristic( nGetChar() );
+    if (nGetChar()==0) /* Q */
+    {
+      //if (f!=NULL) // already tested at start of routine
+      {
+        number n0=nCopy(pGetCoeff(f));
+        if (with_exps==0)
+          N=nCopy(n0);
+        pCleardenom(f);
+        NN=nDiv(n0,pGetCoeff(f));
+        nDelete(&n0);
+        if (with_exps==0)
+        {
+          nDelete(&N);
+          N=nCopy(NN);
+        }
+      }
+    }
+    CanonicalForm F( convSingPClapP( f ) );
+    if (nGetChar()==0) /* Q */
+    {
+      L = factorize( F );
+    }
+    else /* Fp */
+    {
+#ifdef HAVE_LIBFAC_P
+      L = Factorize( F );
+#else
+      goto notImpl;
+#endif
+    }
+  }
+  #if 0
+  else if (rField_is_GF())
+  {
+    int c=rChar(currRing);
+    setCharacteristic( c, primepower(c) );
+    CanonicalForm F( convSingGFClapGF( f ) );
+    if (F.isUnivariate())
+    {
+      L = factorize( F );
+    }
+    else
+    {
+      goto notImpl;
+    }
+  }
+  #endif
+  // and over Q(a) / Fp(a)
+  else if (rField_is_Extension())
+  {
+    if (rField_is_Q_a()) setCharacteristic( 0 );
+    else                 setCharacteristic( -nGetChar() );
+    if (currRing->minpoly!=NULL)
+    {
+      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
+      Variable a=rootOf(mipo);
+      CanonicalForm F( convSingAPClapAP( f,a ) );
+      L.insert(F);
+      if (rField_is_Zp_a() && F.isUnivariate())
+      {
+        L = factorize( F, a );
+      }
+      else
+      {
+        CanonicalForm G( convSingTrPClapP( f ) );
+#ifdef HAVE_LIBFAC_P
+        if (rField_is_Q_a())
+        {
+          CFList as(mipo);
+          L = newfactoras( G, as, 1);
+        }
+        else
+        {
+          L=Factorize(G, mipo);
+        }
+#else
+        WarnS("complete factorization only for univariate polynomials");
+        if (rField_is_Q_a()||(!F.isUnivariate()) /* Q(a) */
+        {
+          L = factorize( G );
+        }
+        else
+        {
+          L = factorize( F, a );
+        }
+#endif
+      }
+    }
+    else
+    {
+      CanonicalForm F( convSingTrPClapP( f ) );
+      if ((rField_is_Q_a())&&(currRing->minpoly!=NULL))
+      {
+        WarnS("factorization may be incomplete");
+        L = factorize( F );
+      }
+      else /* Fp(a) */
+      {
+#ifdef HAVE_LIBFAC_P
+        L = Factorize( F );
+#else
+        goto notImpl;
+#endif
+      }
+    }
+  }
+  else
+  {
+    goto notImpl;
+  }
+  {
+    // the first factor should be a constant
+    if ( ! L.getFirst().factor().inCoeffDomain() )
+      L.insert(CFFactor(1,1));
+    // convert into ideal
+    int n = L.length();
+    CFFListIterator J=L;
+    int j=0;
+    if (with_exps!=1)
+    {
+      if ((with_exps==2)&&(n>1))
+      {
+        n--;
+        J++;
+      }
+      *v = new intvec( n );
+    }
+    res = idInit( n ,1);
+    for ( ; J.hasItem(); J++, j++ )
+    {
+      if (with_exps!=1) (**v)[j] = J.getItem().exp();
+      if (rField_is_Zp() || rField_is_Q())           /* Q, Fp */
+        res->m[j] = convClapPSingP( J.getItem().factor() );
+      #if 0
+      else if (rField_is_GF())
+        res->m[j] = convClapGFSingGF( J.getItem().factor() );
+      #endif
+      else if (rField_is_Extension())     /* Q(a), Fp(a) */
+      {
+        if (currRing->minpoly==NULL)
+          res->m[j] = convClapPSingTrP( J.getItem().factor() );
+        else
+          res->m[j] = convClapAPSingAP( J.getItem().factor() );
+      }
+    }
+    if (N!=NULL)
+    {
+      pMult_nn(res->m[0],N);
+      nDelete(&N);
+      N=NULL;
+    }
+    // delete constants
+    if (res!=NULL)
+    {
+      int i=IDELEMS(res)-1;
+      int j=0;
+      for(;i>=0;i--)
+      {
+        if ((res->m[i]!=NULL)
+        && (pNext(res->m[i])==NULL)
+        && (pIsConstant(res->m[i])))
+        {
+          if (with_exps!=0)
+          {
+            pDelete(&(res->m[i]));
+            if ((v!=NULL) && ((*v)!=NULL))
+              (**v)[i]=0;
+            j++;
+          }
+          else if (i!=0)
+          {
+            res->m[0]=pMult(res->m[0],res->m[i]);
+            res->m[i]=NULL;
+            if ((v!=NULL) && ((*v)!=NULL))
+              (**v)[i]=0;
+            j++;
+          }
+        }
+      }
+      if (j>0)
+      {
+        idSkipZeroes(res);
+        if ((v!=NULL) && ((*v)!=NULL))
+        {
+          intvec *w=*v;
+          *v = new intvec( si_max(n-j,1) );
+          for (i=0,j=0;i<w->length();i++)
+          {
+            if((*w)[i]!=0)
+            {
+              (**v)[j]=(*w)[i]; j++;
+            }
+          }
+          delete w;
+        }
+      }
+      if (res->m[0]==NULL)
+      {
+        res->m[0]=pOne();
+      }
+    }
+  }
+  if (rField_is_Q_a() && (currRing->minpoly!=NULL))
+  {
+    int i=IDELEMS(res)-1;
+    int stop=1;
+    if (with_exps!=0) stop=0;
+    for(;i>=stop;i--)
+    {
+      pNorm(res->m[i]);
+    }
+    if (with_exps==0) pSetCoeff(res->m[0],old_lead_coeff);
+    else nDelete(&old_lead_coeff);
+  }
+  else
+    nDelete(&old_lead_coeff);
+notImpl:
+  if (res==NULL)
+    WerrorS( feNotImplemented );
+  if (NN!=NULL)
+  {
+    pMult_nn(f,NN);
+    nDelete(&NN);
+  }
+  if (N!=NULL)
+  {
+    nDelete(&N);
+  }
+  //PrintS("......S\n");
+  return res;
+}
+
+matrix singclap_irrCharSeries ( ideal I)
+{
+#ifdef HAVE_LIBFAC_P
+  if (idIs0(I)) return mpNew(1,1);
+
+  // for now there is only the possibility to handle polynomials over
+  // Q and Fp ...
+  matrix res=NULL;
+  int i;
+  Off(SW_RATIONAL);
+  On(SW_SYMMETRIC_FF);
+  On(SW_USE_NTL);
+  //Off(SW_USE_NTL);
+  CFList L;
+  ListCFList LL;
+  if (((nGetChar() == 0) || (nGetChar() > 1) )
+  && (currRing->parameter==NULL))
+  {
+    setCharacteristic( nGetChar() );
+    for(i=0;i<IDELEMS(I);i++)
+    {
+      poly p=I->m[i];
+      if (p!=NULL)
+      {
+        p=pCopy(p);
+        pCleardenom(p);
+        L.append(convSingPClapP(p));
+      }
+    }
+  }
+  // and over Q(a) / Fp(a)
+  else if (( nGetChar()==1 ) /* Q(a) */
+  || (nGetChar() <-1))       /* Fp(a) */
+  {
+    if (nGetChar()==1) setCharacteristic( 0 );
+    else               setCharacteristic( -nGetChar() );
+    for(i=0;i<IDELEMS(I);i++)
+    {
+      poly p=I->m[i];
+      if (p!=NULL)
+      {
+        p=pCopy(p);
+        pCleardenom(p);
+        L.append(convSingTrPClapP(p));
+      }
+    }
+  }
+  else
+  {
+    WerrorS( feNotImplemented );
+    return res;
+  }
+
+  // a very bad work-around --- FIX IT in libfac
+  // should be fixed as of 2001/6/27
+  int tries=0;
+  int m,n;
+  ListIterator<CFList> LLi;
+  loop
+  {
+    LL=IrrCharSeries(L);
+    m= LL.length(); // Anzahl Zeilen
+    n=0;
+    for ( LLi = LL; LLi.hasItem(); LLi++ )
+    {
+      n = si_max(LLi.getItem().length(),n);
+    }
+    if ((m!=0) && (n!=0)) break;
+    tries++;
+    if (tries>=5) break;
+  }
+  if ((m==0) || (n==0))
+  {
+    Warn("char_series returns %d x %d matrix from %d input polys (%d)",
+      m,n,IDELEMS(I)+1,LL.length());
+    iiWriteMatrix((matrix)I,"I",2,0);
+    m=si_max(m,1);
+    n=si_max(n,1);
+  }
+  res=mpNew(m,n);
+  CFListIterator Li;
+  for ( m=1, LLi = LL; LLi.hasItem(); LLi++, m++ )
+  {
+    for (n=1, Li = LLi.getItem(); Li.hasItem(); Li++, n++)
+    {
+      if ( (nGetChar() == 0) || (nGetChar() > 1) )
+        MATELEM(res,m,n)=convClapPSingP(Li.getItem());
+      else
+        MATELEM(res,m,n)=convClapPSingTrP(Li.getItem());
+    }
+  }
+  Off(SW_RATIONAL);
+  return res;
+#else
+  return NULL;
+#endif
+}
+
+char* singclap_neworder ( ideal I)
+{
+#ifdef HAVE_LIBFAC_P
+  int i;
+  Off(SW_RATIONAL);
+  On(SW_SYMMETRIC_FF);
+  CFList L;
+  if (((nGetChar() == 0) || (nGetChar() > 1) )
+  && (currRing->parameter==NULL))
+  {
+    setCharacteristic( nGetChar() );
+    for(i=0;i<IDELEMS(I);i++)
+    {
+      L.append(convSingPClapP(I->m[i]));
+    }
+  }
+  // and over Q(a) / Fp(a)
+  else if (( nGetChar()==1 ) /* Q(a) */
+  || (nGetChar() <-1))       /* Fp(a) */
+  {
+    if (nGetChar()==1) setCharacteristic( 0 );
+    else               setCharacteristic( -nGetChar() );
+    for(i=0;i<IDELEMS(I);i++)
+    {
+      L.append(convSingTrPClapP(I->m[i]));
+    }
+  }
+  else
+  {
+    WerrorS( feNotImplemented );
+    return NULL;
+  }
+
+  List<int> IL=neworderint(L);
+  ListIterator<int> Li;
+  StringSetS("");
+  Li = IL;
+  int offs=rPar(currRing);
+  int* mark=(int*)omAlloc0((pVariables+offs)*sizeof(int));
+  int cnt=pVariables+offs;
+  loop
+  {
+    if(! Li.hasItem()) break;
+    BOOLEAN done=TRUE;
+    i=Li.getItem()-1;
+    mark[i]=1;
+    if (i<offs)
+    {
+      done=FALSE;
+      //StringAppendS(currRing->parameter[i]);
+    }
+    else
+    {
+      StringAppendS(currRing->names[i-offs]);
+    }
+    Li++;
+    cnt--;
+    if(cnt==0) break;
+    if (done) StringAppendS(",");
+  }
+  for(i=0;i<pVariables+offs;i++)
+  {
+    BOOLEAN done=TRUE;
+    if(mark[i]==0)
+    {
+      if (i<offs)
+      {
+        done=FALSE;
+        //StringAppendS(currRing->parameter[i]);
+      }
+      else
+      {
+        StringAppendS(currRing->names[i-offs]);
+      }
+      cnt--;
+      if(cnt==0) break;
+      if (done) StringAppendS(",");
+    }
+  }
+  char * s=omStrDup(StringAppendS(""));
+  if (s[strlen(s)-1]==',') s[strlen(s)-1]='\0';
+  return s;
+#else
+  return NULL;
+#endif
+}
+
+BOOLEAN singclap_isSqrFree(poly f)
+{
+  BOOLEAN b=FALSE;
+  Off(SW_RATIONAL);
+  //  Q / Fp
+  if (((nGetChar() == 0) || (nGetChar() > 1) )
+  &&(currRing->parameter==NULL))
+  {
+    setCharacteristic( nGetChar() );
+    CanonicalForm F( convSingPClapP( f ) );
+    if((nGetChar()>1)&&(!F.isUnivariate()))
+      goto err;
+    b=(BOOLEAN)isSqrFree(F);
+  }
+  // and over Q(a) / Fp(a)
+  else if (( nGetChar()==1 ) /* Q(a) */
+  || (nGetChar() <-1))       /* Fp(a) */
+  {
+    if (nGetChar()==1) setCharacteristic( 0 );
+    else               setCharacteristic( -nGetChar() );
+    //if (currRing->minpoly!=NULL)
+    //{
+    //  CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
+    //  Variable a=rootOf(mipo);
+    //  CanonicalForm F( convSingAPClapAP( f,a ) );
+    //  ...
+    //}
+    //else
+    {
+      CanonicalForm F( convSingTrPClapP( f ) );
+      b=(BOOLEAN)isSqrFree(F);
+    }
+    Off(SW_RATIONAL);
+  }
+  else
+  {
+err:
+    WerrorS( feNotImplemented );
+  }
+  return b;
+}
+
+poly singclap_det( const matrix m )
+{
+  int r=m->rows();
+  if (r!=m->cols())
+  {
+    Werror("det of %d x %d matrix",r,m->cols());
+    return NULL;
+  }
+  poly res=NULL;
+  if (( nGetChar() == 0 || nGetChar() > 1 )
+  && (currRing->parameter==NULL))
+  {
+    setCharacteristic( nGetChar() );
+    CFMatrix M(r,r);
+    int i,j;
+    for(i=r;i>0;i--)
+    {
+      for(j=r;j>0;j--)
+      {
+        M(i,j)=convSingPClapP(MATELEM(m,i,j));
+      }
+    }
+    res= convClapPSingP( determinant(M,r) ) ;
+  }
+  // and over Q(a) / Fp(a)
+  else if (( nGetChar()==1 ) /* Q(a) */
+  || (nGetChar() <-1))       /* Fp(a) */
+  {
+    if (nGetChar()==1) setCharacteristic( 0 );
+    else               setCharacteristic( -nGetChar() );
+    CFMatrix M(r,r);
+    poly res;
+    if (currRing->minpoly!=NULL)
+    {
+      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
+      Variable a=rootOf(mipo);
+      int i,j;
+      for(i=r;i>0;i--)
+      {
+        for(j=r;j>0;j--)
+        {
+          M(i,j)=convSingAPClapAP(MATELEM(m,i,j),a);
+        }
+      }
+      res= convClapAPSingAP( determinant(M,r) ) ;
+    }
+    else
+    {
+      int i,j;
+      for(i=r;i>0;i--)
+      {
+        for(j=r;j>0;j--)
+        {
+          M(i,j)=convSingTrPClapP(MATELEM(m,i,j));
+        }
+      }
+      res= convClapPSingTrP( determinant(M,r) );
+    }
+  }
+  else
+    WerrorS( feNotImplemented );
+  Off(SW_RATIONAL);
+  return res;
+}
+
+int singclap_det_i( intvec * m )
+{
+  setCharacteristic( 0 );
+  CFMatrix M(m->rows(),m->cols());
+  int i,j;
+  for(i=m->rows();i>0;i--)
+  {
+    for(j=m->cols();j>0;j--)
+    {
+      M(i,j)=IMATELEM(*m,i,j);
+    }
+  }
+  int res= convClapISingI( determinant(M,m->rows())) ;
+  Off(SW_RATIONAL);
+  return res;
+}
+napoly singclap_alglcm ( napoly f, napoly g )
+{
+ FACTORY_ALGOUT( "f", f );
+ FACTORY_ALGOUT( "g", g );
+
+ // over Q(a) / Fp(a)
+ if (nGetChar()==1) setCharacteristic( 0 );
+ else               setCharacteristic( -nGetChar() );
+ napoly res;
+
+ if (currRing->minpoly!=NULL)
+ {
+   CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
+   Variable a=rootOf(mipo);
+   CanonicalForm F( convSingAClapA( f,a ) ), G( convSingAClapA( g,a ) );
+   CanonicalForm GCD;
+
+   TIMING_START( algLcmTimer );
+   // calculate gcd
+#ifdef FACTORY_GCD_TEST
+   GCD = CFPrimitiveGcdUtil::gcd( F, G );
+#else
+   GCD = gcd( F, G );
+#endif
+   TIMING_END( algLcmTimer );
+
+   FACTORY_CFAOUT( "d", GCD );
+   FACTORY_GCDSTAT( "alcm:", F, G, GCD );
+
+   // calculate lcm
+   res= convClapASingA( (F/GCD)*G );
+ }
+ else
+ {
+   CanonicalForm F( convSingTrClapP( f ) ), G( convSingTrClapP( g ) );
+   CanonicalForm GCD;
+   TIMING_START( algLcmTimer );
+   // calculate gcd
+#ifdef FACTORY_GCD_TEST
+   GCD = CFPrimitiveGcdUtil::gcd( F, G );
+#else
+   GCD = gcd( F, G );
+#endif
+   TIMING_END( algLcmTimer );
+
+   FACTORY_CFTROUT( "d", GCD );
+   FACTORY_GCDSTAT( "alcm:", F, G, GCD );
+
+   // calculate lcm
+   res= convClapPSingTr( (F/GCD)*G );
+ }
+
+ Off(SW_RATIONAL);
+ return res;
+}
+
+void singclap_algdividecontent ( napoly f, napoly g, napoly &ff, napoly &gg )
+{
+ FACTORY_ALGOUT( "f", f );
+ FACTORY_ALGOUT( "g", g );
+
+ // over Q(a) / Fp(a)
+ if (nGetChar()==1) setCharacteristic( 0 );
+ else               setCharacteristic( -nGetChar() );
+ ff=gg=NULL;
+ On(SW_RATIONAL);
+
+ if (currRing->minpoly!=NULL)
+ {
+   CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
+   Variable a=rootOf(mipo);
+   CanonicalForm F( convSingAClapA( f,a ) ), G( convSingAClapA( g,a ) );
+   CanonicalForm GCD;
+
+   TIMING_START( algContentTimer );
+#ifdef FACTORY_GCD_TEST
+   GCD=CFPrimitiveGcdUtil::gcd( F, G );
+#else
+   GCD=gcd( F, G );
+#endif
+   TIMING_END( algContentTimer );
+
+   FACTORY_CFAOUT( "d", GCD );
+   FACTORY_GCDSTAT( "acnt:", F, G, GCD );
+
+   if ((GCD!=1) && (GCD!=0))
+   {
+     ff= convClapASingA( F/ GCD );
+     gg= convClapASingA( G/ GCD );
+   }
+ }
+ else
+ {
+   CanonicalForm F( convSingTrClapP( f ) ), G( convSingTrClapP( g ) );
+   CanonicalForm GCD;
+
+   TIMING_START( algContentTimer );
+#ifdef FACTORY_GCD_TEST
+   GCD=CFPrimitiveGcdUtil::gcd( F, G );
+#else
+   GCD=gcd( F, G );
+#endif
+   TIMING_END( algContentTimer );
+
+   FACTORY_CFTROUT( "d", GCD );
+   FACTORY_GCDSTAT( "acnt:", F, G, GCD );
+
+   if ((GCD!=1) && (GCD!=0))
+   {
+     ff= convClapPSingTr( F/ GCD );
+     gg= convClapPSingTr( G/ GCD );
+   }
+ }
+
+ Off(SW_RATIONAL);
+}
+
+#if 0
+lists singclap_chineseRemainder(lists x, lists q)
+{
+  //assume(x->nr == q->nr);
+  //assume(x->nr >= 0);
+  int n=x->nr+1;
+  if ((x->nr<0) || (x->nr!=q->nr))
+  {
+    WerrorS("list are empty or not of equal length");
+    return NULL;
+  }
+  lists res=(lists)omAlloc0Bin(slists_bin);
+  CFArray X(1,n), Q(1,n);
+  int i;
+  for(i=0; i<n; i++)
+  {
+    if (x->m[i-1].Typ()==INT_CMD)
+    {
+      X[i]=(int)x->m[i-1].Data();
+    }
+    else if (x->m[i-1].Typ()==NUMBER_CMD)
+    {
+      number N=(number)x->m[i-1].Data();
+      X[i]=convSingNClapN(N);
+    }
+    else
+    {
+      WerrorS("illegal type in chineseRemainder");
+      omFreeBin(res,slists_bin);
+      return NULL;
+    }
+    if (q->m[i-1].Typ()==INT_CMD)
+    {
+      Q[i]=(int)q->m[i-1].Data();
+    }
+    else if (q->m[i-1].Typ()==NUMBER_CMD)
+    {
+      number N=(number)x->m[i-1].Data();
+      Q[i]=convSingNClapN(N);
+    }
+    else
+    {
+      WerrorS("illegal type in chineseRemainder");
+      omFreeBin(res,slists_bin);
+      return NULL;
+    }
+  }
+  CanonicalForm r, prod;
+  chineseRemainder( X, Q, r, prod );
+  res->Init(2);
+  res->m[0].rtyp=NUMBER_CMD;
+  res->m[1].rtyp=NUMBER_CMD;
+  res->m[0].data=(char *)convClapNSingN( r );
+  res->m[1].data=(char *)convClapNSingN( prod );
+  return res;
+}
+#endif
+#endif
Index: kernel/clapsing.h
===================================================================
--- kernel/clapsing.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/clapsing.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,50 @@
+// emacs edit mode for this file is -*- C++ -*-
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+// $Id: clapsing.h,v 1.1.1.1 2003-10-06 12:15:50 Singular Exp $
+/*
+* ABSTRACT: interface between Singular and factory
+*/
+
+
+#ifndef INCL_FACTORYSING_H
+#define INCL_FACTORYSING_H
+
+#include "structs.h"
+#include "polys.h"
+#include "ideals.h"
+#include "intvec.h"
+#include "matpol.h"
+
+poly singclap_gcd ( poly f, poly g );
+napoly singclap_alglcm ( napoly f, napoly g );
+void singclap_algdividecontent ( napoly f, napoly g, napoly &ff, napoly &gg );
+
+poly singclap_resultant ( poly f, poly g , poly x);
+
+BOOLEAN singclap_extgcd ( poly f, poly g, poly &res, poly &pa, poly &pb );
+
+poly singclap_pdivide ( poly f, poly g );
+
+void singclap_divide_content ( poly f );
+
+ideal singclap_factorize ( poly f, intvec ** v , int with_exps);
+
+matrix singclap_irrCharSeries ( ideal I);
+
+BOOLEAN singclap_isSqrFree(poly f);
+
+char* singclap_neworder ( ideal I);
+
+poly singclap_det( const matrix m );
+int singclap_det_i( intvec * m );
+
+BOOLEAN jjRESULTANT(leftv res, leftv u, leftv v, leftv w);
+BOOLEAN jjCHARSERIES(leftv res, leftv u);
+#if 0
+BOOLEAN jjIS_SQR_FREE(leftv res, leftv u);
+#endif
+
+#endif /* INCL_FACTORYSING_H */
+
Index: kernel/claptmpl.cc
===================================================================
--- kernel/claptmpl.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/claptmpl.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,213 @@
+// emacs edit mode for this file is -*- C++ -*-
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+// $Id: claptmpl.cc,v 1.1.1.1 2003-10-06 12:15:50 Singular Exp $
+/*
+* ABSTRACT - instantiation of all templates
+*/
+
+#include "mod2.h"
+
+#ifdef HAVE_FACTORY
+  #define SINGULAR 1
+  #include <factory.h>
+#endif
+
+#if defined(HAVE_FACTORY) || defined(HAVE_FGLM)
+  #include <templates/ftmpl_list.cc>
+  #ifdef HAVE_FGLM
+    #include "fglm.h"
+  #endif
+
+  #ifdef HAVE_FACTORY
+    #include <templates/ftmpl_array.cc>
+    #include <templates/ftmpl_factor.cc>
+    #include <templates/ftmpl_functions.h>
+    #include <templates/ftmpl_matrix.cc>
+    #ifdef __MWERKS__
+      template List<CanonicalForm> Difference<CanonicalForm>(const List<CanonicalForm>&,const List<CanonicalForm>&);
+      template List<CanonicalForm> Union<CanonicalForm>(const List<CanonicalForm>&,const List<CanonicalForm>&);
+      template List<CFFactor> Union<CFFactor>(const List<CFFactor>&,const List<CFFactor>&);
+      template List<Variable> Union<Variable> ( const List<Variable>&, const List<Variable>& );
+      template List<Variable> Difference<Variable> ( const List<Variable>&, const List<Variable>& );
+      template int operator==<CanonicalForm> ( const Factor<CanonicalForm>&, const Factor<CanonicalForm>& );
+    #endif
+
+    template class Factor<CanonicalForm>;
+    template class List<CFFactor>;
+    template class ListItem<CFFactor>;
+    template class ListItem<CanonicalForm>;
+    template class ListIterator<CFFactor>;
+    template class List<CanonicalForm>;
+    template class List<List<CanonicalForm> >;
+    template class ListIterator<CanonicalForm>;
+    template class Array<CanonicalForm>;
+    template class List<MapPair>;
+    template class ListItem<MapPair>;
+    template class ListIterator<MapPair>;
+    template class Matrix<CanonicalForm>;
+    template class SubMatrix<CanonicalForm>;
+    template class Array<REvaluation>;
+
+    #ifndef NOSTREAMIO
+    template ostream & operator<<(ostream &, const List<Factor<CanonicalForm> > &);
+    template ostream & operator<<(ostream &, const List<List<CanonicalForm> > &);
+    template ostream & operator<<(ostream &, const List<Variable> &);
+    #endif
+
+    #ifndef __MWERKS__
+      template List<CFFactor> Union ( const List<CFFactor>&, const List<CFFactor>& );
+      template int operator == ( const Factor<CanonicalForm>&, const Factor<CanonicalForm>& );
+
+      template CanonicalForm tmax ( const CanonicalForm&, const CanonicalForm& );
+      template CanonicalForm tmin ( const CanonicalForm&, const CanonicalForm& );
+
+      template Variable tmax ( const Variable&, const Variable& );
+      template Variable tmin ( const Variable&, const Variable& );
+
+      template int tmax ( const int&, const int& );
+      template int tmin ( const int&, const int& );
+      template int tabs ( const int& );
+    #endif
+
+  #endif
+// place here your own template stuff, not instantiated by factory
+  #ifdef HAVE_LIBFAC_P
+    #include <factor.h>
+
+// class.h:
+template <class T>
+class Substitution {
+private:
+    T _factor;
+    T _exp;
+public:
+    Substitution() : _factor(1), _exp(0) {}
+    Substitution( const Substitution<T> & f ) : _factor(f._factor), _exp(f._exp) {}
+    Substitution( const T & f, const T & e ) : _factor(f), _exp(e) {}
+    Substitution( const T & f ) : _factor(f), _exp(1) {}
+    ~Substitution() {}
+    Substitution<T>& operator= ( const Substitution<T>& );
+    Substitution<T>& operator= ( const T& );
+    T factor() const { return _factor; }
+    T exp() const { return _exp; }
+#ifndef NOSTREAMIO
+    friend ostream & operator <<<>(ostream &, Substitution<T> &);
+    void Substitution<T>::print ( ostream& s ) const
+    {
+      s << "("  << factor() << ")^" << exp();
+    }
+#endif
+};
+template <class T>
+int operator== ( const Substitution<T>&, const Substitution<T>& );
+
+// class.cc
+template <class T>
+Substitution<T>& Substitution<T>::operator= ( const Substitution<T>& f )
+{
+    if ( this != &f ) {
+        _factor = f._factor;
+        _exp = f._exp;
+    }
+    return *this;
+}
+
+template <class T>
+Substitution<T>& Substitution<T>::operator= ( const T & f )
+{
+    _factor = f;
+    _exp = 1;
+    return *this;
+}
+
+#ifndef NOSTREAMIO
+template <class T>
+ostream & operator <<(ostream & os, Substitution<T> &a)
+{
+  a.print(os);
+  return os;
+}
+template ostream & operator <<(ostream &, Substitution<CanonicalForm> &);
+template ostream & operator <<(ostream &, const List<CanonicalForm> &);
+template ostream & operator <<(ostream &, const Array<CanonicalForm> &);
+template ostream & operator<<(ostream &, const List<Substitution<CanonicalForm> > &);
+#endif
+
+template <class T>
+int operator== ( const Substitution<T> &f1, const Substitution<T> &f2 )
+{
+    return (f1.exp() == f2.exp()) && (f1.factor() == f2.factor());
+}
+
+    template class List<int>;
+    template class ListIterator<int>;
+
+    template class List<IntList>;
+    template class ListIterator<IntList>;
+
+    template class Substitution<CanonicalForm>;
+    template class Array<Variable>;
+    template class Array<int>;
+    typedef Substitution<CanonicalForm> SForm ;
+    template class List<SForm>;
+    template class ListIterator<SForm>;
+    template class List<Variable>;
+    template class ListIterator<Variable> ;
+
+    #ifndef __MWERKS__
+      template List<Variable> Union ( const List<Variable>&, const List<Variable>& );
+      template List<Variable> Difference ( const List<Variable>&, const List<Variable>& );
+
+      template List<CanonicalForm> Union ( const List<CanonicalForm>&, const List<CanonicalForm>& );
+      template List<CanonicalForm> Difference ( const List<CanonicalForm>&, const List<CanonicalForm>& );
+    #endif
+
+// for charsets:
+    template class ListIterator<CFList>;
+
+  #endif
+#endif
+
+#ifdef HAVE_FGLM
+// templates for fglm:
+
+  template class List<fglmSelem>;
+  template class ListIterator<fglmSelem>;
+
+  template class List<fglmDelem>;
+  template class ListIterator<fglmDelem>;
+#endif
+
+// ----------------------------------------------------------------------------
+//  kmatrix.cc
+//  begin of file
+//  Stephan Endrass, endrass@mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#ifdef HAVE_SPECTRUM
+
+#ifdef   KMATRIX_PRINT
+#include <iostream.h>
+#ifndef   KMATRIX_IOSTREAM
+#include <stdio.h>
+#endif
+#endif
+
+#include "GMPrat.h"
+#include "kmatrix.h"
+
+template    class   KMatrix<Rational>;
+
+#ifdef   KMATRIX_PRINT
+template    ostream &   operator << ( ostream&,const KMatrix<Rational>& );
+template    static  void    print_rational( ostream&,int,const Rational& );
+#endif
+
+#endif /* HAVE_SPECTRUM */
+// ----------------------------------------------------------------------------
+//  kmatrix.cc
+//  end of file
+// ----------------------------------------------------------------------------
Index: kernel/cntrlc.h
===================================================================
--- kernel/cntrlc.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/cntrlc.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,19 @@
+#ifndef CNTRLC_H
+#define CNTRLC_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: cntrlc.h,v 1.1.1.1 2003-10-06 12:15:50 Singular Exp $ */
+/*
+* ABSTRACT - interupt and signal handling
+*/
+#include <setjmp.h>
+#include "structs.h"
+
+extern jmp_buf si_start_jmpbuf;
+extern short si_restart;
+extern int siRandomStart;
+extern BOOLEAN siCntrlc;
+void init_signals();
+
+#endif
Index: kernel/config.log
===================================================================
--- kernel/config.log	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/config.log	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,121 @@
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+configure:561: checking uname for singular
+configure:658: checking for gcc
+configure:771: checking whether the C compiler (gcc -O ) works
+configure:787: gcc -o conftest -O   conftest.c  1>&5
+configure:813: checking whether the C compiler (gcc -O ) is a cross-compiler
+configure:818: checking whether we are using GNU C
+configure:846: checking whether gcc accepts -g
+configure:878: checking how to run the C preprocessor
+configure:962: checking for c++
+configure:994: checking whether the C++ compiler (c++ -O ) works
+configure:1010: c++ -o conftest -O   conftest.C  1>&5
+configure:1036: checking whether the C++ compiler (c++ -O ) is a cross-compiler
+configure:1041: checking whether we are using GNU C++
+configure:1069: checking whether c++ accepts -g
+configure:1131: checking for a BSD compatible install
+configure:1184: checking for AIX
+configure:1212: checking gcc version
+configure:1244: checking whether gcc accepts --no-rtti
+configure:1279: checking whether gcc accepts --no-exceptions
+configure:1325: checking whether compiler accepts -pipe
+configure:1363: checking whether _AIX is defined
+configure:1419: checking whether make sets ${MAKE}
+configure:1502: checking for flex
+configure:1574: checking for bison
+configure:1609: checking whether ln -s works
+configure:1635: checking for perl5
+configure:1670: checking for atof in -lm
+configure:1780: checking for dlopen in -ldl
+configure:1907: checking for ANSI C header files
+configure:2014: checking for limits.h
+configure:2014: checking for unistd.h
+configure:2058: checking for sys/file.h
+configure:2058: checking for sys/ioctl.h
+configure:2058: checking for sys/time.h
+configure:2058: checking for sys/times.h
+configure:2058: checking for sys/types.h
+configure:2058: checking for sys/stat.h
+configure:2058: checking for fcntl.h
+configure:2058: checking for sys/param.h
+configure:2058: checking for pwd.h
+configure:2058: checking for asm/sigcontext.h
+configure:2058: checking for pwd.h
+configure:2058: checking for termcap.h
+configure:2058: checking for termios.h
+configure:2058: checking for term.h
+configure:2058: checking for readline/readline.h
+configure:2097: checking for working const
+configure:2172: checking for inline
+configure:2212: checking for size_t
+configure:2245: checking whether struct tm is in sys/time.h or time.h
+configure:2279: checking whether time.h and sys/time.h may both be included
+configure:2318: checking for working alloca.h
+configure:2351: checking for alloca
+configure:2551: checking whether gcc needs -traditional
+configure:2600: checking for unistd.h
+configure:2639: checking for getpagesize
+configure:2692: checking for working mmap
+configure:2863: checking return type of signal handlers
+configure:2904: checking for vprintf
+configure:3010: checking for library containing setenv
+configure:3074: checking for gettimeofday
+configure:3074: checking for atexit
+configure:3074: checking for bcopy
+configure:3074: checking for getcwd
+configure:3074: checking for getwd
+configure:3074: checking for vsnprintf
+configure:3074: checking for readlink
+configure:3074: checking for sleep
+configure:3074: checking for usleep
+configure:3074: checking for getpwnam
+configure:3074: checking for popen
+configure:3074: checking for setenv
+configure:3131: checking whether your machine has correct arithmetic shifts
+configure:3173: checking whether explicit C++ constructor calls are allowed
+configure:3233: checking whether vsprintf returns number of printed chars
+configure:3272: checking size of char
+configure:3311: checking size of short
+configure:3350: checking size of int
+configure:3389: checking size of long
+configure:3428: checking size of void*
+configure:3467: checking size of double
+configure:3506: checking whether byte ordering is bigendian
+configure:3698: checking whether to use dynamic linking
+configure:3711: checking for tgetent in -lncurses
+configure:3871: checking for rl_abort in -lreadline
+configure:3921: checking how to run the C++ preprocessor
+configure:3967: checking for readline/readline.h
+configure:3967: checking for readline/history.h
+configure:4006: checking whether readline.h is ok
+configure:4040: checking whether or not we nevertheless can use readline
+configure:4118: checking which readline to use
+configure:4138: checking for main in -lgmp
+configure:4184: checking for main in -lsmallgmp
+configure:4228: checking for IMP_PutGmpInt in -lMP
+configure:4275: checking for MPT_GetTree in -lMPT
+configure:4323: checking for atof in -lsingcf
+configure:4370: checking for atof in -lsingfac
+configure:4417: checking for omTestAddr in -lomalloc
+configure:4464: checking for main in -lomalloc_ndebug
+configure:4507: checking for main in -lntl
+configure:4555: checking for gmp.h
+configure:4555: checking for smallgmp.h
+configure:4555: checking for MP.h
+configure:4555: checking for MPT.h
+configure:4555: checking for factory.h
+configure:4555: checking for factor.h
+configure:4555: checking for omalloc.h
+configure:4555: checking for omalloc.c
+configure:4637: checking which apint package to use
+configure:4679: checking whether to have MP
+configure:4714: checking whether to have NTL
+configure:4723: checking whether to have factory
+configure:4754: checking whether to have libfac
+configure:4788: checking whether to have dbm links
+configure:4800: checking whether to have namespaces
+configure:4812: checking whether to have dynamic modules
+configure:4824: checking whether to have dynamic kernel
+configure:4834: checking whether to have Plural
Index: kernel/configure
===================================================================
--- kernel/configure	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/configure	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,5237 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_default_prefix=`pwd`/..
+ac_help="$ac_help
+  --with-rootdir=DIR      use DIR ass compiled-in root directory
+                             (default is PREFIX)"
+ac_help="$ac_help
+  --with-lex=[LEX,no]     uses LEX as lex program, default is flex"
+ac_help="$ac_help
+  --with-readline=[dynamic,static,no]          
+                          do use dynamic/static/no readline for fancy display"
+ac_help="$ac_help
+  --without-MP            do not use MP (no MP links)"
+ac_help="$ac_help
+  --without-dbm           do not use dbm (no DBM links)"
+ac_help="$ac_help
+  --without-factory       do not use factory (no poly factorization)"
+ac_help="$ac_help
+  --without-libfac        do not use libfac (no primary decompositions)"
+ac_help="$ac_help
+  --with-namespaces       do compile namespace support"
+ac_help="$ac_help
+  --without-dl            do not use dynamic linking, modules, and kernel"
+ac_help="$ac_help
+  --with-dynamic-modules  do compile with dynamic modules support"
+ac_help="$ac_help
+  --without-dynamic-kernel               
+                          do not compile with dynamic kernel parts"
+ac_help="$ac_help
+  --with-apint=PACKAGE    use PACKAGE for arbitary integer arithmetic"
+ac_help="$ac_help
+  --with-Plural           do compile with Plural support"
+ac_help="$ac_help
+  --with-NTL              build for use with NTL."
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.13"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=mmalloc.cc
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='	'
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+
+echo $ac_n "checking uname for singular""... $ac_c" 1>&6
+echo "configure:561: checking uname for singular" >&5
+if eval "test \"`echo '$''{'ac_cv_singuname'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_singuname="unknown"
+if test -r "singuname.sh"; then
+  if (/bin/sh singuname.sh >/dev/null 2>&1) then
+    ac_cv_singuname=`/bin/sh singuname.sh`
+  fi
+fi
+if test "$ac_cv_singuname" = unknown && test -r "../singuname.sh"; then
+  if (/bin/sh ../singuname.sh >/dev/null 2>&1) then
+    ac_cv_singuname=`/bin/sh ../singuname.sh`
+  fi
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_singuname" 1>&6
+if test "$ac_cv_singuname" = unknown; then
+  echo "configure: warning: Unknown architecture: Check singuname.sh" 1>&2
+  ac_cv_singuname="unknown"
+fi
+cat >> confdefs.h <<EOF
+#define S_UNAME "$ac_cv_singuname"
+EOF
+
+SINGUNAME=$ac_cv_singuname
+
+
+if test "$ac_cv_singuname" = ix86-Win; then
+  EXEC_EXT=".exe"
+fi
+
+
+SING_UNAME=`echo $SINGUNAME | tr '-' '_' `
+
+
+# stupid Win programs do not like dots in their pathnames
+VERSION_SEP="-"
+
+
+SINGULAR_MAJOR_VERSION=${SINGULAR_MAJOR_VERSION:-2}
+SINGULAR_MINOR_VERSION=${SINGULAR_MINOR_VERSION:-1}
+SINGULAR_SUB_VERSION=${SINGULAR_SUB_VERSION:-2}
+SINGULAR_VERSION="${SINGULAR_VERSION:-$SINGULAR_MAJOR_VERSION${VERSION_SEP}$SINGULAR_MINOR_VERSION${VERSION_SEP}$SINGULAR_SUB_VERSION}"
+VERSION_DATE=${VERSION_DATE:-"August 2001"}
+
+
+
+
+
+
+cat >> confdefs.h <<EOF
+#define SINGULAR_MAJOR_VERSION ${SINGULAR_MAJOR_VERSION}
+EOF
+
+cat >> confdefs.h <<EOF
+#define SINGULAR_MINOR_VERSION ${SINGULAR_MINOR_VERSION}
+EOF
+
+cat >> confdefs.h <<EOF
+#define SINGULAR_SUB_VERSION ${SINGULAR_SUB_VERSION}
+EOF
+
+cat >> confdefs.h <<EOF
+#define S_VERSION1 "${SINGULAR_MAJOR_VERSION}${VERSION_SEP}${SINGULAR_MINOR_VERSION}${VERSION_SEP}${SINGULAR_SUB_VERSION}"
+EOF
+
+cat >> confdefs.h <<EOF
+#define S_VERSION2 "${VERSION_DATE}"
+EOF
+
+cat >> confdefs.h <<EOF
+#define SINGULAR_SUB_VERSION ${SINGULAR_SUB_VERSION}
+EOF
+
+
+
+if test "${CXXFLAGS+set}" != set; then
+  ac_cxxflags_set=no
+  CXXFLAGS="-O"
+fi
+if test "${CFLAGS+set}" != set; then
+  CFLAGS="-O"
+  ac_cflags_set=no
+fi
+
+# check whether CXX was set by user as env variable
+if test "${CXX+set}" != set; then
+  ac_cxx_set=no
+else
+  ac_cxx_set=yes
+fi
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:658: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:688: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+	continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:739: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:771: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 782 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:787: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:813: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:818: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:827: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:846: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:878: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    # This must be in double quotes, not single quotes, because CPP may get
+  # substituted into the Makefile and "${CC-cc}" will confuse make.
+  CPP="${CC-cc} -E"
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp.
+  cat > conftest.$ac_ext <<EOF
+#line 893 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:899: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -E -traditional-cpp"
+  cat > conftest.$ac_ext <<EOF
+#line 910 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:916: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -nologo -E"
+  cat > conftest.$ac_ext <<EOF
+#line 927 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:933: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+  ac_cv_prog_CPP="$CPP"
+fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:962: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CXX="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CXX="$ac_cv_prog_CXX"
+if test -n "$CXX"; then
+  echo "$ac_t""$CXX" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CXX" && break
+done
+test -n "$CXX" || CXX="gcc"
+
+
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:994: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1005 "configure"
+#include "confdefs.h"
+
+int main(){return(0);}
+EOF
+if { (eval echo configure:1010: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cxx_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cxx_cross=no
+  else
+    ac_cv_prog_cxx_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cxx_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
+if test $ac_cv_prog_cxx_works = no; then
+  { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1036: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
+echo "configure:1041: checking whether we are using GNU C++" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.C <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1050: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gxx=yes
+else
+  ac_cv_prog_gxx=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gxx" 1>&6
+
+if test $ac_cv_prog_gxx = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+
+ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ac_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS=
+echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
+echo "configure:1069: checking whether ${CXX-g++} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.cc
+if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
+  ac_cv_prog_cxx_g=yes
+else
+  ac_cv_prog_cxx_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS="$ac_save_CXXFLAGS"
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:1131: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    IFS="${IFS= 	}"; ac_save_IFS="$IFS"; IFS=":"
+  for ac_dir in $PATH; do
+    # Account for people who put trailing slashes in PATH elements.
+    case "$ac_dir/" in
+    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+    *)
+      # OSF1 and SCO ODT 3.0 have their own names for install.
+      # Don't use installbsd from OSF since it installs stuff as root
+      # by default.
+      for ac_prog in ginstall scoinst install; do
+        if test -f $ac_dir/$ac_prog; then
+	  if test $ac_prog = install &&
+            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  else
+	    ac_cv_path_install="$ac_dir/$ac_prog -c"
+	    break 2
+	  fi
+	fi
+      done
+      ;;
+    esac
+  done
+  IFS="$ac_save_IFS"
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking for AIX""... $ac_c" 1>&6
+echo "configure:1184: checking for AIX" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1186 "configure"
+#include "confdefs.h"
+#ifdef _AIX
+  yes
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "yes" >/dev/null 2>&1; then
+  rm -rf conftest*
+  echo "$ac_t""yes" 1>&6; cat >> confdefs.h <<\EOF
+#define _ALL_SOURCE 1
+EOF
+
+else
+  rm -rf conftest*
+  echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+
+
+
+# test for gcc-version: gcc2: prefer CC=gcc, CXX=gcc
+#                       gcc3:        CC=gcc  CXX=g++
+#                       other:       CC=cc   CXX=c++
+echo $ac_n "checking gcc version""... $ac_c" 1>&6
+echo "configure:1212: checking gcc version" >&5
+if eval "test \"`echo '$''{'ac_cv_c_cpp'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_c_cp="unknown"
+if test -r "gccversion.sh"; then
+  ac_cv_c_cpp=`/bin/sh gccversion.sh`
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_cpp" 1>&6
+
+# we prefer using gcc for compiling C++ files, provided the user did
+# not overwrite it explicitely
+if test "${GXX}" = yes && test "${ac_cxx_set}" = no; then
+  if test "${ac_cv_c_cpp}" = gcc2; then
+    CXX=gcc
+  elif test "${ac_cv_c_cpp}" = gcc3; then
+    CXX=g++
+  fi
+  temp_cflags=${CXXFLAGS}
+  
+  ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+  # check whether gcc accepts --no-rtti
+  echo $ac_n "checking whether gcc accepts --no-rtti""... $ac_c" 1>&6
+echo "configure:1244: checking whether gcc accepts --no-rtti" >&5
+  CXXFLAGS="${CXXFLAGS} --no-rtti"
+  if eval "test \"`echo '$''{'ac_cv_cxx_have_rtti'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1250 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1257: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_cxx_have_rtti=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_cxx_have_rtti=no
+fi
+rm -f conftest*
+  
+fi
+
+  echo "$ac_t""${ac_cv_cxx_have_rtti}" 1>&6
+  if test "${ac_cv_cxx_have_rtti}" != yes; then
+  CXXFLAGS=$temp_flags
+  else
+  CXX="${CXX} --no-rtti"
+  fi
+
+# check whether gcc accepts --no-exceptions
+  echo $ac_n "checking whether gcc accepts --no-exceptions""... $ac_c" 1>&6
+echo "configure:1279: checking whether gcc accepts --no-exceptions" >&5
+  CXXFLAGS="${CXXFLAGS} --no-exceptions"
+  if eval "test \"`echo '$''{'ac_cv_cxx_have_exceptions'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1285 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1292: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_cv_cxx_have_exceptions=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_cxx_have_exceptions=no
+fi
+rm -f conftest*
+  
+fi
+
+  echo "$ac_t""${ac_cv_cxx_have_exceptions}" 1>&6
+  if test "${ac_cv_cxx_have_exceptions}" != yes; then
+  CXXFLAGS=$temp_flags
+  else
+  CXX="${CXX} --no-exceptions"
+  fi
+
+  ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+  CXXFLAGS=$temp_flags
+
+fi
+
+# check whether the compiler accepts -pipe
+echo $ac_n "checking whether compiler accepts -pipe""... $ac_c" 1>&6
+echo "configure:1325: checking whether compiler accepts -pipe" >&5
+temp_cflags=${CFLAGS}
+CFLAGS="${CFLAGS} -pipe"
+if eval "test \"`echo '$''{'ac_cv_cxx_have_pipe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1332 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1339: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_cxx_have_pipe=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_cxx_have_pipe=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""${ac_cv_cxx_have_pipe}" 1>&6
+CFLAGS=${temp_cflags}
+if test "${ac_cv_cxx_have_pipe}" != yes; then
+  PIPE=
+else
+  PIPE="-pipe"
+fi
+
+
+# Customize CFLAGS
+echo $ac_n "checking whether _AIX is defined""... $ac_c" 1>&6
+echo "configure:1363: checking whether _AIX is defined" >&5
+if eval "test \"`echo '$''{'ac_cv_is_aix'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1368 "configure"
+#include "confdefs.h"
+#ifdef _AIX
+    yes
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "yes" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_is_aix=yes
+else
+  rm -rf conftest*
+  ac_cv_is_aix=no
+fi
+rm -f conftest*
+
+fi
+
+if test "$ac_cv_is_aix" = yes; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+# we know best when compiling with gcc
+if test "${GXX}" = yes; then
+  if test "$ac_cxxflags_set" = no; then
+    CXXFLAGS="-O3 -w -fomit-frame-pointer"
+  fi
+  CXXTEMPLFLAGS="-fno-implicit-templates"
+  if test "$ac_cv_is_aix" = yes; then
+    CXXNOOPTFLAGS="-w"
+  else
+    CXXNOOPTFLAGS=$CXXFLAGS
+  fi
+  STATIC_LDFLAGS="-static"
+else
+  CXXTEMPFLAGS=""
+  CXXNOOPTFLAGS=$CXXFLAGS
+  STATIC_LDFLAGS=""
+fi
+
+
+
+
+if test "${GCC}" = yes && test "$ac_cflags_set" = no ; then
+  CFLAGS="-O3 -w -fomit-frame-pointer"
+fi
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:1419: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftestmake <<\EOF
+all:
+	@echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  SET_MAKE=
+else
+  echo "$ac_t""no" 1>&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+
+
+
+# expand prefix
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+if test "${with_rootdir+set}" != set; then
+  cat >> confdefs.h <<EOF
+#define S_ROOT_DIR "${prefix}"
+EOF
+
+else
+  cat >> confdefs.h <<EOF
+#define S_ROOT_DIR "${with_rootdir}"
+EOF
+
+fi
+
+# expand exec_prefixad
+if test "x$exec_prefix" = xNONE; then
+ exec_prefix=${prefix}/${ac_cv_singuname}
+fi
+
+# expand bindir
+test "x$bindir" = 'x${exec_prefix}/bin' && bindir="${exec_prefix}"
+SINGULAR=${SINGULAR:-$bindir/Singular-$SINGULAR_MAJOR_VERSION${VERSION_SEP}$SINGULAR_MINOR_VERSION${VERSION_SEP}$SINGULAR_SUB_VERSION}
+
+cat >> confdefs.h <<EOF
+#define S_BIN_DIR "${bindir}"
+EOF
+
+
+# expand libdir
+test "x$libdir" = 'x${exec_prefix}/lib'&& libdir="${exec_prefix}/lib"
+
+# expand includedir
+test "x$includedir" = 'x${prefix}/include' && includedir="${exec_prefix}/include"
+
+# add to -I to CPPFLAGS and and -L to LDFLAGS, just to be sure
+if test "$ac_cv_c_cpp" = gcc3 ; then
+  LDFLAGS="-L${libdir} ${LDFLAGS}"
+  CPPFLAGS="-I${includedir} ${CPPFLAGS}"
+else
+  LDFLAGS="-L${libdir} ${LDFLAGS} -L/usr/local/lib"
+  CPPFLAGS="-I${includedir} ${CPPFLAGS} -I/usr/local/include"
+fi
+
+# this is a work-around to include the right term.h
+if test "$ac_cv_singuname" = SunOS-5; then
+CPPFLAGS="-I/usr/xpg4/include ${CPPFLAGS}"
+fi
+
+
+
+# lex
+if test "${with_lex+set}" != set; then
+  echo $ac_n "checking for flex""... $ac_c" 1>&6
+echo "configure:1502: checking for flex" >&5
+    cmd="egrep [2-9]\.[5-9]"
+    if eval "test \"`echo '$''{'ac_cv_prog_flex'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if (flex --version >/dev/null 2>&1)
+    then
+    if (flex --version | $cmd >/dev/null 2>&1 )
+    then
+	ac_cv_prog_flex=flex
+    fi
+  fi
+  
+fi
+
+    if test "${ac_cv_prog_flex+set}" = set; then
+    echo "$ac_t""flex" 1>&6
+    LEX=flex
+    
+  else
+    { echo "configure: error: can not find flex with version greater 2.4" 1>&2; exit 1; }
+  fi
+elif test "${with_lex}" = no; then
+  echo "configure: warning: building without lex -- make might fail" 1>&2
+else
+  unset LEX
+  unset ac_cv_prog_LEX
+  for ac_prog in ${with_lex}
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1534: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$LEX"; then
+  ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_LEX="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+  echo "$ac_t""$LEX" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$LEX" && break
+done
+
+  if test "x${LEX}" = x; then
+    echo "configure: warning: building without lex -- make might fail" 1>&2
+  fi
+fi
+
+# bison
+for ac_prog in bison
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1574: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_BISON'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$BISON"; then
+  ac_cv_prog_BISON="$BISON" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_BISON="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+BISON="$ac_cv_prog_BISON"
+if test -n "$BISON"; then
+  echo "$ac_t""$BISON" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$BISON" && break
+done
+
+if test "${BISON+set}" != set; then
+  echo "configure: warning: did not find bison -- make might fail" 1>&2
+fi
+
+# ln -s
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1609: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+  rm -f conftestdata
+  ac_cv_prog_LN_S="ln -s"
+else
+  ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+for ac_prog in perl5 perl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1635: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_PERL'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$PERL"; then
+  ac_cv_prog_PERL="$PERL" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_PERL="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+PERL="$ac_cv_prog_PERL"
+if test -n "$PERL"; then
+  echo "$ac_t""$PERL" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$PERL" && break
+done
+
+
+# lib checks
+# under cygwin, we should not explicitly link with -lm, except for
+# it really is the last thing to link with
+if test "$ac_cv_singuname" != ix86-Win; then
+echo $ac_n "checking for atof in -lm""... $ac_c" 1>&6
+echo "configure:1670: checking for atof in -lm" >&5
+ac_lib_var=`echo m'_'atof | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lm  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1678 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char atof();
+
+int main() {
+atof()
+; return 0; }
+EOF
+if { (eval echo configure:1689: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lm $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+SAVE_LIBS=${LIBS}
+LIBS=
+
+# check for dl lib
+case "$ac_cv_singuname" in
+	HPUX*)
+	  echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
+echo "configure:1724: checking for shl_load in -ldld" >&5
+ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldld  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1732 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char shl_load();
+
+int main() {
+shl_load()
+; return 0; }
+EOF
+if { (eval echo configure:1743: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo dld | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-ldld $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+	  if test "$ac_cv_lib_dld_shl_load" = yes; then
+         	LD_DYN_FLAGS="-ldld -Xlinker -E"
+	  	SFLAGS="-fpic -fPIC -DPIC"
+	  	SLDFLAGS="-fPIC -DPIC -shared"
+		LD=gcc
+		ac_lib_dl=yes
+	  fi
+	;;
+	*Linux*)
+	  echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "configure:1780: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1788 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:1799: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo dl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-ldl $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+          if test "$ac_cv_lib_dl_dlopen" = yes; then
+	  	LD_DYN_FLAGS="-ldl -rdynamic"
+	  	SFLAGS="-fpic -DPIC"
+	  	SLDFLAGS=-shared
+		LD=ld
+	        ac_lib_dl=yes
+	  fi
+	;;
+        IRIX-6)
+          LD_DYN_FLAGS="-lc"
+	  SFLAGS="-fPIC -DPIC"
+	  SLDFLAGS="-w -no_unresolved -_SYSTYPE_SVR4 -n32 -shared"
+          LD=ld
+	  ac_lib_dl=yes
+        ;;
+	SunOS-5)
+	  echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "configure:1843: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1851 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:1862: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo dl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-ldl $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+          if test "$ac_cv_lib_dl_dlopen" = yes; then
+	  	LD_DYN_FLAGS="-ldl -Xlinker -E"
+	  	SFLAGS="-fpic -DPIC"
+	  	SLDFLAGS=-shared
+                LD=ld
+	        ac_lib_dl=yes
+	  fi
+	;;
+esac
+
+
+
+
+LIBS=${SAVE_LIBS}
+
+
+# heder file checks
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1907: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1912 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1920: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  ac_cv_header_stdc=yes
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1937 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "memchr" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1955 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "free" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+  :
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1976 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1987: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+  cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+for ac_hdr in limits.h unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2014: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2019 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2024: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+{ echo "configure: error: Can not compile without limits.h unistd.h" 1>&2; exit 1; }
+fi
+done
+
+
+for ac_hdr in sys/file.h sys/ioctl.h sys/time.h sys/times.h sys/types.h \
+ sys/stat.h fcntl.h sys/param.h pwd.h asm/sigcontext.h pwd.h termcap.h \
+ termios.h term.h readline/readline.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2058: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2063 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2068: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+# typedefs, structures
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:2097: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2102 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this.  */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this.  */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this.  */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+   It does not let you subtract one const X* pointer from another in an arm
+   of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this.  */
+  char *t;
+  char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+  *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+  int x[] = {25, 17};
+  const int *foo = &x[0];
+  ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+  typedef const int *iptr;
+  iptr p = 0;
+  ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+     "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+  struct s { int j; const int *ap[3]; };
+  struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+  const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:2151: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_const=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+  cat >> confdefs.h <<\EOF
+#define const 
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:2172: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat > conftest.$ac_ext <<EOF
+#line 2179 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:2186: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_inline=$ac_kw; break
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+  inline | yes) ;;
+  no) cat >> confdefs.h <<\EOF
+#define inline 
+EOF
+ ;;
+  *)  cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:2212: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2217 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_size_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+  cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
+echo "configure:2245: checking whether struct tm is in sys/time.h or time.h" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2250 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <time.h>
+int main() {
+struct tm *tp; tp->tm_sec;
+; return 0; }
+EOF
+if { (eval echo configure:2258: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_struct_tm=time.h
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_tm" 1>&6
+if test $ac_cv_struct_tm = sys/time.h; then
+  cat >> confdefs.h <<\EOF
+#define TM_IN_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:2279: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2284 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:2293: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_header_time=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+  cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+
+# library functions.
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments.  Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:2318: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2323 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:2330: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_cv_header_alloca_h=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:2351: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2356 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+#  include <malloc.h>
+#  define alloca _alloca
+# else
+#  if HAVE_ALLOCA_H
+#   include <alloca.h>
+#  else
+#   ifdef _AIX
+ #pragma alloca
+#   else
+#    ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:2384: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_cv_func_alloca_works=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+  # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+  # that cause trouble.  Some versions do not even contain alloca or
+  # contain a buggy version.  If you still want to use their alloca,
+  # use ar to extract alloca.o from them instead of compiling alloca.c.
+  ALLOCA=alloca.${ac_objext}
+  cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:2416: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2421 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "webecray" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_os_cray=yes
+else
+  rm -rf conftest*
+  ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+  echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2446: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2451 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2474: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+  break
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:2501: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_c_stack_direction=0
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2509 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+  static char *addr = 0;
+  auto char dummy;
+  if (addr == 0)
+    {
+      addr = &dummy;
+      return find_stack_direction ();
+    }
+  else
+    return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+  exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:2528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_c_stack_direction=1
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+if test $ac_cv_prog_gcc = yes; then
+    echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
+echo "configure:2551: checking whether ${CC-cc} needs -traditional" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    ac_pattern="Autoconf.*'x'"
+  cat > conftest.$ac_ext <<EOF
+#line 2557 "configure"
+#include "confdefs.h"
+#include <sgtty.h>
+Autoconf TIOCGETP
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "$ac_pattern" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_prog_gcc_traditional=yes
+else
+  rm -rf conftest*
+  ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+  if test $ac_cv_prog_gcc_traditional = no; then
+    cat > conftest.$ac_ext <<EOF
+#line 2575 "configure"
+#include "confdefs.h"
+#include <termio.h>
+Autoconf TCGETA
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "$ac_pattern" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+  fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
+  if test $ac_cv_prog_gcc_traditional = yes; then
+    CC="$CC -traditional"
+  fi
+fi
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2600: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2605 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2610: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2639: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2644 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2667: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:2692: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_func_mmap_fixed_mapped=no
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2700 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+   Here is a matrix of mmap possibilities:
+	mmap private not fixed
+	mmap private fixed at somewhere currently unmapped
+	mmap private fixed at somewhere already mapped
+	mmap shared not fixed
+	mmap shared fixed at somewhere currently unmapped
+	mmap shared fixed at somewhere already mapped
+   For private mappings, we should verify that changes cannot be read()
+   back from the file, nor mmap's back from the file at a different
+   address.  (There have been systems where private was not correctly
+   implemented like the infamous i386 svr4.0, and systems where the
+   VM page cache was not coherent with the filesystem buffer cache
+   like early versions of FreeBSD and possibly contemporary NetBSD.)
+   For shared mappings, we should conversely verify that changes get
+   propogated back to all the places they're supposed to be.
+
+   Grep wants private fixed already mapped.
+   The main things grep needs to know about mmap are:
+   * does it exist and is it safe to write into the mmap'd area
+   * how to use it (BSD variants)  */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h.  */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h.  */
+# ifndef HAVE_SYS_PARAM_H
+#  define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+#  define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+#  ifdef HAVE_SYS_PARAM_H
+#   include <sys/param.h>
+#   ifdef EXEC_PAGESIZE
+#    define getpagesize() EXEC_PAGESIZE
+#   else /* no EXEC_PAGESIZE */
+#    ifdef NBPG
+#     define getpagesize() NBPG * CLSIZE
+#     ifndef CLSIZE
+#      define CLSIZE 1
+#     endif /* no CLSIZE */
+#    else /* no NBPG */
+#     ifdef NBPC
+#      define getpagesize() NBPC
+#     else /* no NBPC */
+#      ifdef PAGESIZE
+#       define getpagesize() PAGESIZE
+#      endif /* PAGESIZE */
+#     endif /* no NBPC */
+#    endif /* no NBPG */
+#   endif /* no EXEC_PAGESIZE */
+#  else /* no HAVE_SYS_PARAM_H */
+#   define getpagesize() 8192	/* punt totally */
+#  endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+	char *data, *data2, *data3;
+	int i, pagesize;
+	int fd;
+
+	pagesize = getpagesize();
+
+	/*
+	 * First, make a file with some known garbage in it.
+	 */
+	data = malloc(pagesize);
+	if (!data)
+		exit(1);
+	for (i = 0; i < pagesize; ++i)
+		*(data + i) = rand();
+	umask(0);
+	fd = creat("conftestmmap", 0600);
+	if (fd < 0)
+		exit(1);
+	if (write(fd, data, pagesize) != pagesize)
+		exit(1);
+	close(fd);
+
+	/*
+	 * Next, try to mmap the file at a fixed address which
+	 * already has something else allocated at it.  If we can,
+	 * also make sure that we see the same garbage.
+	 */
+	fd = open("conftestmmap", O_RDWR);
+	if (fd < 0)
+		exit(1);
+	data2 = malloc(2 * pagesize);
+	if (!data2)
+		exit(1);
+	data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+	if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+	    MAP_PRIVATE | MAP_FIXED, fd, 0L))
+		exit(1);
+	for (i = 0; i < pagesize; ++i)
+		if (*(data + i) != *(data2 + i))
+			exit(1);
+
+	/*
+	 * Finally, make sure that changes to the mapped area
+	 * do not percolate back to the file as seen by read().
+	 * (This is a bug on some variants of i386 svr4.0.)
+	 */
+	for (i = 0; i < pagesize; ++i)
+		*(data2 + i) = *(data2 + i) + 1;
+	data3 = malloc(pagesize);
+	if (!data3)
+		exit(1);
+	if (read(fd, data3, pagesize) != pagesize)
+		exit(1);
+	for (i = 0; i < pagesize; ++i)
+		if (*(data + i) != *(data3 + i))
+			exit(1);
+	close(fd);
+	unlink("conftestmmap");
+	exit(0);
+}
+
+EOF
+if { (eval echo configure:2840: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_func_mmap_fixed_mapped=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:2863: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2868 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:2885: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_type_signal=void
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_type_signal=int
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+echo $ac_n "checking for vprintf""... $ac_c" 1>&6
+echo "configure:2904: checking for vprintf" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2909 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char vprintf(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char vprintf();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_vprintf) || defined (__stub___vprintf)
+choke me
+#else
+vprintf();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2932: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_vprintf=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_vprintf=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define HAVE_VPRINTF 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test "$ac_cv_func_vprintf" != yes; then
+echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
+echo "configure:2956: checking for _doprnt" >&5
+if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2961 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char _doprnt(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char _doprnt();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub__doprnt) || defined (__stub____doprnt)
+choke me
+#else
+_doprnt();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2984: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func__doprnt=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func__doprnt=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define HAVE_DOPRNT 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+
+echo $ac_n "checking for library containing setenv""... $ac_c" 1>&6
+echo "configure:3010: checking for library containing setenv" >&5
+if eval "test \"`echo '$''{'ac_cv_search_setenv'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_setenv="no"
+cat > conftest.$ac_ext <<EOF
+#line 3017 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char setenv();
+
+int main() {
+setenv()
+; return 0; }
+EOF
+if { (eval echo configure:3028: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_cv_search_setenv="none required"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+test "$ac_cv_search_setenv" = "no" && for i in bsd; do
+LIBS="-l$i  $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3039 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char setenv();
+
+int main() {
+setenv()
+; return 0; }
+EOF
+if { (eval echo configure:3050: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_cv_search_setenv="-l$i"
+break
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+LIBS="$ac_func_search_save_LIBS"
+fi
+
+echo "$ac_t""$ac_cv_search_setenv" 1>&6
+if test "$ac_cv_search_setenv" != "no"; then
+  test "$ac_cv_search_setenv" = "none required" || LIBS="$ac_cv_search_setenv $LIBS"
+  
+else :
+  
+fi
+for ac_func in gettimeofday atexit bcopy getcwd getwd vsnprintf readlink \
+ sleep usleep getpwnam popen setenv
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3074: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3079 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3102: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+
+# arithmetic shifts
+echo $ac_n "checking whether your machine has correct arithmetic shifts""... $ac_c" 1>&6
+echo "configure:3131: checking whether your machine has correct arithmetic shifts" >&5
+if eval "test \"`echo '$''{'ac_cv_shift'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  if test "$ac_c_cross_dos" = yes; then
+     ac_cv_shift=yes;
+   else
+     echo "$ac_t""no" 1>&6
+     { echo "configure: error: cross compilation without default value" 1>&2; exit 1; }
+   fi
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3144 "configure"
+#include "confdefs.h"
+ int main() { if (-2 >> 1 == -1) exit(0); else exit(1); } 
+EOF
+if { (eval echo configure:3148: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_shift=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_shift=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+
+if test "$ac_cv_shift" = yes; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+  { echo "configure: error: need  -2 >> 1 == -1" 1>&2; exit 1; }
+fi
+
+
+# check for a peculiar constructor initialization
+echo $ac_n "checking whether explicit C++ constructor calls are allowed""... $ac_c" 1>&6
+echo "configure:3173: checking whether explicit C++ constructor calls are allowed" >&5
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+if eval "test \"`echo '$''{'ac_cv_explicit_const'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3186 "configure"
+#include "confdefs.h"
+
+int main() {
+class testclass
+  {
+  public:
+    int value;
+    testclass() : value(0) {}
+    testclass( int i ) : value(i) {}
+    ~testclass() { value = 0; }
+  };
+
+  testclass ptr;
+  ptr.testclass(1);
+
+; return 0; }
+EOF
+if { (eval echo configure:3204: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_explicit_const=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_explicit_const=no
+fi
+rm -f conftest*
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_explicit_const" 1>&6
+if test "$ac_cv_explicit_const" = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_EXPLICIT_CONSTR 1
+EOF
+
+fi
+
+# sprintf returns number of printed chars
+echo $ac_n "checking whether vsprintf returns number of printed chars""... $ac_c" 1>&6
+echo "configure:3233: checking whether vsprintf returns number of printed chars" >&5
+if eval "test \"`echo '$''{'ac_cv_returns_n_of_chars'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_returns_n_of_chars=no
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3241 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+ main() { char *str=(char*)malloc(20); if (((int) sprintf(str,"123456789")) == 9) exit(0); else exit(1); }
+EOF
+if { (eval echo configure:3246: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_returns_n_of_chars=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_returns_n_of_chars=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+if test "$ac_cv_returns_n_of_chars" = yes; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+  cat >> confdefs.h <<\EOF
+#define BSD_SPRINTF 1
+EOF
+
+fi
+
+# determine ALIGN_8
+echo $ac_n "checking size of char""... $ac_c" 1>&6
+echo "configure:3272: checking size of char" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_char'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof_char=1
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3280 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(char));
+  exit(0);
+}
+EOF
+if { (eval echo configure:3291: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_char=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_char=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_char" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_CHAR $ac_cv_sizeof_char
+EOF
+
+
+echo $ac_n "checking size of short""... $ac_c" 1>&6
+echo "configure:3311: checking size of short" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof_short=2
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3319 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(short));
+  exit(0);
+}
+EOF
+if { (eval echo configure:3330: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_short=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_short=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_short" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+EOF
+
+
+echo $ac_n "checking size of int""... $ac_c" 1>&6
+echo "configure:3350: checking size of int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof_int=4
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3358 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(int));
+  exit(0);
+}
+EOF
+if { (eval echo configure:3369: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_int=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_int=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_int" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+EOF
+
+
+echo $ac_n "checking size of long""... $ac_c" 1>&6
+echo "configure:3389: checking size of long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof_long=4
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3397 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(long));
+  exit(0);
+}
+EOF
+if { (eval echo configure:3408: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_long=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+EOF
+
+
+echo $ac_n "checking size of void*""... $ac_c" 1>&6
+echo "configure:3428: checking size of void*" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_voidp'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof_voidp=4
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3436 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(void*));
+  exit(0);
+}
+EOF
+if { (eval echo configure:3447: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_voidp=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_voidp=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_voidp" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_VOIDP $ac_cv_sizeof_voidp
+EOF
+
+
+echo $ac_n "checking size of double""... $ac_c" 1>&6
+echo "configure:3467: checking size of double" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_double'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof_double=8
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3475 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(double));
+  exit(0);
+}
+EOF
+if { (eval echo configure:3486: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_double=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_double=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_double" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_DOUBLE $ac_cv_sizeof_double
+EOF
+
+
+echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
+echo "configure:3506: checking whether byte ordering is bigendian" >&5
+if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+cat > conftest.$ac_ext <<EOF
+#line 3513 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:3524: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat > conftest.$ac_ext <<EOF
+#line 3528 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:3539: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_bigendian=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_bigendian=no
+fi
+rm -f conftest*
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+if test $ac_cv_c_bigendian = unknown; then
+if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3559 "configure"
+#include "confdefs.h"
+main () {
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+EOF
+if { (eval echo configure:3572: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_c_bigendian=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_c_bigendian=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_bigendian" 1>&6
+if test $ac_cv_c_bigendian = yes; then
+  cat >> confdefs.h <<\EOF
+#define WORDS_BIGENDIAN 1
+EOF
+
+fi
+
+if test "$ac_cv_sizeof_int" != 4; then
+  { echo "configure: error: need int to be four bytes long" 1>&2; exit 1; }
+fi
+if test "$ac_cv_sizeof_long" != "$ac_cv_sizeof_voidp"; then
+  { echo "configure: error: need equal sizes for long and void*" 1>&2; exit 1; }
+fi
+if test "$ac_cv_sizeof_double" != 8; then
+  { echo "configure: error: need double to b 8 bytes long" 1>&2; exit 1; }
+fi
+if test "$ac_cv_sizeof_voidp" != 4 && test "$ac_cv_sizeof_voidp" != 8; then
+  { echo "configure: error: need void* to be 4 or 8 bytes long" 1>&2; exit 1; }
+fi
+
+# Check whether --with-rootdir or --without-rootdir was given.
+if test "${with_rootdir+set}" = set; then
+  withval="$with_rootdir"
+  :
+fi
+
+# Check whether --with-lex or --without-lex was given.
+if test "${with_lex+set}" = set; then
+  withval="$with_lex"
+  :
+fi
+
+# Check whether --with-readline or --without-readline was given.
+if test "${with_readline+set}" = set; then
+  withval="$with_readline"
+  :
+fi
+
+# Check whether --with-MP or --without-MP was given.
+if test "${with_MP+set}" = set; then
+  withval="$with_MP"
+  :
+fi
+
+# Check whether --with-dbm or --without-dbm was given.
+if test "${with_dbm+set}" = set; then
+  withval="$with_dbm"
+  :
+fi
+
+# Check whether --with-factory or --without-factory was given.
+if test "${with_factory+set}" = set; then
+  withval="$with_factory"
+  :
+fi
+
+# Check whether --with-libfac or --without-libfac was given.
+if test "${with_libfac+set}" = set; then
+  withval="$with_libfac"
+  :
+fi
+
+# Check whether --with-namespaces or --without-namespaces was given.
+if test "${with_namespaces+set}" = set; then
+  withval="$with_namespaces"
+  :
+fi
+
+# Check whether --with-dl or --without-dl was given.
+if test "${with_dl+set}" = set; then
+  withval="$with_dl"
+  :
+fi
+
+# Check whether --with-dynamic-modules or --without-dynamic-modules was given.
+if test "${with_dynamic_modules+set}" = set; then
+  withval="$with_dynamic_modules"
+  :
+fi
+ 
+# Check whether --with-dynamic-kernel or --without-dynamic-kernel was given.
+if test "${with_dynamic_kernel+set}" = set; then
+  withval="$with_dynamic_kernel"
+  :
+fi
+
+# Check whether --with-apint or --without-apint was given.
+if test "${with_apint+set}" = set; then
+  withval="$with_apint"
+  :
+fi
+
+# Check whether --with-Plural or --without-Plural was given.
+if test "${with_Plural+set}" = set; then
+  withval="$with_Plural"
+  :
+fi
+
+# Check whether --with-NTL or --without-NTL was given.
+if test "${with_NTL+set}" = set; then
+  withval="$with_NTL"
+  :
+else
+  with_NTL=yes
+fi
+
+
+
+
+echo $ac_n "checking whether to use dynamic linking""... $ac_c" 1>&6
+echo "configure:3698: checking whether to use dynamic linking" >&5
+if test "$with_dl" != no && test "$ac_lib_dl" = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_DL 1
+EOF
+
+  ac_have_dl=yes
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for tgetent in -lncurses""... $ac_c" 1>&6
+echo "configure:3711: checking for tgetent in -lncurses" >&5
+ac_lib_var=`echo ncurses'_'tgetent | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lncurses  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3719 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char tgetent();
+
+int main() {
+tgetent()
+; return 0; }
+EOF
+if { (eval echo configure:3730: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo ncurses | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lncurses $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+\
+ echo $ac_n "checking for tgetent in -lcurses""... $ac_c" 1>&6
+echo "configure:3757: checking for tgetent in -lcurses" >&5
+ac_lib_var=`echo curses'_'tgetent | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lcurses  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3765 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char tgetent();
+
+int main() {
+tgetent()
+; return 0; }
+EOF
+if { (eval echo configure:3776: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo curses | sed -e 's/^a-zA-Z0-9_/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lcurses $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+\
+  echo $ac_n "checking for tgetent in -ltermcap""... $ac_c" 1>&6
+echo "configure:3803: checking for tgetent in -ltermcap" >&5
+ac_lib_var=`echo termcap'_'tgetent | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ltermcap  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3811 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char tgetent();
+
+int main() {
+tgetent()
+; return 0; }
+EOF
+if { (eval echo configure:3822: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo termcap | sed -e 's/^a-zA-Z0-9_/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-ltermcap $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+fi
+
+
+# readline
+if test "$with_readline" = dynamic && test "$ac_have_dl" != yes; then
+  echo "configure: warning: can not build dynamic readline without dynamic linking" 1>&2
+  with_readline=static
+fi
+
+
+if test "$with_readline" != dynamic && test "$with_readline" != no; then
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+   echo $ac_n "checking for rl_abort in -lreadline""... $ac_c" 1>&6
+echo "configure:3871: checking for rl_abort in -lreadline" >&5
+ac_lib_var=`echo readline'_'rl_abort | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lreadline  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3879 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char rl_abort();
+
+int main() {
+rl_abort()
+; return 0; }
+EOF
+if { (eval echo configure:3893: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo readline | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lreadline $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+   echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6
+echo "configure:3921: checking how to run the C++ preprocessor" >&5
+if test -z "$CXXCPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+  CXXCPP="${CXX-g++} -E"
+  cat > conftest.$ac_ext <<EOF
+#line 3934 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3939: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CXXCPP=/lib/cpp
+fi
+rm -f conftest*
+  ac_cv_prog_CXXCPP="$CXXCPP"
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+fi
+fi
+CXXCPP="$ac_cv_prog_CXXCPP"
+echo "$ac_t""$CXXCPP" 1>&6
+
+for ac_hdr in readline/readline.h readline/history.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:3967: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3972 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3977: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+   if test "$ac_cv_lib_readline_rl_abort" = yes && \
+      test "$ac_cv_header_readline_readline_h" = yes; then
+     echo $ac_n "checking whether readline.h is ok""... $ac_c" 1>&6
+echo "configure:4006: checking whether readline.h is ok" >&5
+     if eval "test \"`echo '$''{'ac_cv_header_readline_readline_h_ok'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 4011 "configure"
+#include "confdefs.h"
+#include<unistd.h>
+#include<stdio.h>
+#include<readline/readline.h>
+#ifdef HAVE_READLINE_HISTORY_H
+#include<readline/history.h>
+#endif
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:4024: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_cv_header_readline_readline_h_ok="yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_readline_readline_h_ok="no"
+fi
+rm -f conftest*
+fi
+
+    echo "$ac_t""$ac_cv_header_readline_readline_h_ok" 1>&6
+    if test "$ac_cv_header_readline_readline_h_ok" != yes; then
+#not ok -- try once more with explicitly declaring everything
+      echo $ac_n "checking whether or not we nevertheless can use readline""... $ac_c" 1>&6
+echo "configure:4040: checking whether or not we nevertheless can use readline" >&5
+      if eval "test \"`echo '$''{'ac_cv_have_readline'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 4045 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+extern "C"
+{
+extern char * rl_readline_name;
+extern char *rl_line_buffer;
+char *filename_completion_function();
+typedef char **CPPFunction ();
+extern char ** completion_matches ();
+extern CPPFunction * rl_attempted_completion_function;
+extern FILE * rl_outstream;
+char * readline ();
+void add_history ();
+int write_history ();
+int read_history();
+}
+#ifndef NULL
+#define NULL 0
+#endif
+
+int main() {
+rl_readline_name=NULL;
+*rl_line_buffer=1;
+completion_matches(NULL, filename_completion_function);
+rl_attempted_completion_function = (CPPFunction *) NULL;
+rl_outstream=NULL;
+readline(NULL);
+add_history(NULL);
+read_history(NULL);
+write_history(NULL);
+
+; return 0; }
+EOF
+if { (eval echo configure:4079: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_cv_have_readline="yes"
+
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_have_readline="no"
+
+fi
+rm -f conftest*
+fi
+
+      echo "$ac_t""$ac_cv_have_readline" 1>&6
+    else
+      cat >> confdefs.h <<\EOF
+#define READLINE_READLINE_H_OK 1
+EOF
+
+      ac_cv_have_readline="yes"
+    fi
+  fi
+  if test "$ac_cv_have_readline" = yes; then
+    cat >> confdefs.h <<\EOF
+#define HAVE_READLINE 1
+EOF
+
+  fi
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+fi
+
+echo $ac_n "checking which readline to use""... $ac_c" 1>&6
+echo "configure:4118: checking which readline to use" >&5
+if test "$ac_cv_with_readline" = dynamic; then
+  echo "$ac_t""dynamic" 1>&6
+  cat >> confdefs.h <<\EOF
+#define HAVE_DYN_RL 1
+EOF
+
+elif test "$ac_cv_have_readline" = yes; then
+  echo "$ac_t""static" 1>&6
+elif test "$ac_cv_singuname" = PowerMacintosh-darwin; then
+  { echo "configure: error: building without readline impossible on PowerMacintosh-darwin" 1>&2; exit 1; }
+else
+  echo "$ac_t""none" 1>&6
+  echo "configure: warning: building without readline: disabling fancy display" 1>&2
+fi
+  
+NEED_LIBS=$LIBS
+
+# gmp, smallgmp, MP, MPT, factory, libfac
+echo $ac_n "checking for main in -lgmp""... $ac_c" 1>&6
+echo "configure:4138: checking for main in -lgmp" >&5
+ac_lib_var=`echo gmp'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lgmp  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4146 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:4153: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo gmp | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lgmp $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test "ac_cv_lib_gmp_main" = yes && test "$with-apint" = smallgmp; then
+  LIBS=${NEED_LIBS}
+fi
+echo $ac_n "checking for main in -lsmallgmp""... $ac_c" 1>&6
+echo "configure:4184: checking for main in -lsmallgmp" >&5
+ac_lib_var=`echo smallgmp'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lsmallgmp  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4192 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:4199: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo smallgmp | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lsmallgmp $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+SAVE_LIBS=$LIBS
+echo $ac_n "checking for IMP_PutGmpInt in -lMP""... $ac_c" 1>&6
+echo "configure:4228: checking for IMP_PutGmpInt in -lMP" >&5
+ac_lib_var=`echo MP'_'IMP_PutGmpInt | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lMP $MP_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4236 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char IMP_PutGmpInt();
+
+int main() {
+IMP_PutGmpInt()
+; return 0; }
+EOF
+if { (eval echo configure:4247: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo MP | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lMP $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for MPT_GetTree in -lMPT""... $ac_c" 1>&6
+echo "configure:4275: checking for MPT_GetTree in -lMPT" >&5
+ac_lib_var=`echo MPT'_'MPT_GetTree | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lMPT $MP_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4283 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char MPT_GetTree();
+
+int main() {
+MPT_GetTree()
+; return 0; }
+EOF
+if { (eval echo configure:4294: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo MPT | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lMPT $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+LIBS=$SAVE_LIBS
+echo $ac_n "checking for atof in -lsingcf""... $ac_c" 1>&6
+echo "configure:4323: checking for atof in -lsingcf" >&5
+ac_lib_var=`echo singcf'_'atof | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lsingcf  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4331 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char atof();
+
+int main() {
+atof()
+; return 0; }
+EOF
+if { (eval echo configure:4342: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo singcf | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lsingcf $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for atof in -lsingfac""... $ac_c" 1>&6
+echo "configure:4370: checking for atof in -lsingfac" >&5
+ac_lib_var=`echo singfac'_'atof | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lsingfac  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4378 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char atof();
+
+int main() {
+atof()
+; return 0; }
+EOF
+if { (eval echo configure:4389: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo singfac | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lsingfac $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for omTestAddr in -lomalloc""... $ac_c" 1>&6
+echo "configure:4417: checking for omTestAddr in -lomalloc" >&5
+ac_lib_var=`echo omalloc'_'omTestAddr | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lomalloc  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4425 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char omTestAddr();
+
+int main() {
+omTestAddr()
+; return 0; }
+EOF
+if { (eval echo configure:4436: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo omalloc | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lomalloc $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for main in -lomalloc_ndebug""... $ac_c" 1>&6
+echo "configure:4464: checking for main in -lomalloc_ndebug" >&5
+ac_lib_var=`echo omalloc_ndebug'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lomalloc_ndebug  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4472 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:4479: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo omalloc_ndebug | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lomalloc_ndebug $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for main in -lntl""... $ac_c" 1>&6
+echo "configure:4507: checking for main in -lntl" >&5
+ac_lib_var=`echo ntl'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lntl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4515 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:4522: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo ntl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lntl $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+for ac_hdr in gmp.h smallgmp.h MP.h  MPT.h factory.h factor.h omalloc.h \
+ omalloc.c
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:4555: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 4560 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4565: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+if test "$ac_cv_lib_gmp_main" = yes && \
+ test "$ac_cv_header_gmp_h" = yes; then
+    ac_gmp_ok=yes
+fi
+
+if test "$ac_cv_lib_smallgmp_main" = yes && \
+ test "$ac_cv_header_smallgmp_h" = yes && \
+ test "$ac_cv_header_gmp_h" = yes; then
+    ac_smallgmp_ok=yes
+fi
+
+if test "$ac_cv_lib_MP_IMP_PutGmpInt" = yes && \
+ test "$ac_cv_lib_MPT_MPT_GetTree" && \
+ test "$ac_cv_header_MP_h" = yes && \
+ test "$ac_cv_header_MPT_h" = yes; then
+  ac_MP_ok=yes
+fi
+
+if test "$ac_cv_lib_singcf_atof" = yes && \
+ test "$ac_cv_header_factory_h" = yes; then
+  ac_factory_ok=yes
+fi
+
+if test "$ac_cv_lib_singfac_atof" = yes && \
+ test "$ac_cv_header_factor_h" = yes; then
+  ac_libfac_ok=yes
+fi
+
+if test "$ac_cv_lib_omalloc_omTestAddr" = yes && \
+   test "$ac_cv_lib_omalloc_ndebug_main" = yes && \
+   test "$ac_cv_header_omalloc_c" = yes && \
+   test "$ac_cv_header_omalloc_h" = yes; then
+  ac_cv_omalloc_ok=yes
+fi
+
+if test "$ac_cv_lib_ntl_main" = yes; then
+  ac_cv_ntl_ok=yes
+fi
+
+# evaluate results
+if test "$ac_cv_omalloc_ok" != yes && test "$enable_omalloc" != yes; then
+  { echo "configure: error: can not build without omalloc" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking which apint package to use""... $ac_c" 1>&6
+echo "configure:4637: checking which apint package to use" >&5
+if test "${with_apint}" != gmp && test "${with_apint}" != smallgmp; then
+  if test "$ac_gmp_ok" = yes || test "$enable_gmp" = yes; then
+    echo "$ac_t""gmp" 1>&6
+    will_have_gmp=yes
+    NEED_LIBS="-lgmp ${NEED_LIBS}"
+  elif test "ac_gmp_smallgmp_ok" = yes || test "$enable_smallgmp" = "yes"; then
+    echo "$ac_t""smallgmp" 1>&6
+    cat >> confdefs.h <<\EOF
+#define HAVE_SMALLGMP 1
+EOF
+
+    NEED_LIBS="-lsmallgmp ${NEED_LIBS}"
+  else
+    echo "$ac_t""none" 1>&6
+    { echo "configure: error: can not build without gmp or smallgmp" 1>&2; exit 1; }
+  fi
+elif test "${with_apint}" = gmp; then
+  if test "$ac_gmp_ok" = yes || test "$enable_gmp" = yes; then
+    echo "$ac_t""gmp" 1>&6
+    will_have_gmp=yes
+    NEED_LIBS="-lgmp ${NEED_LIBS}"
+  else
+    echo "$ac_t""none" 1>&6
+    { echo "configure: error: can not build with gmp" 1>&2; exit 1; }
+  fi
+else
+  if test "ac_gmp_smallgmp_ok" = yes || test "$enable_smallgmp" = "yes"; then
+    echo "$ac_t""smallgmp" 1>&6
+    cat >> confdefs.h <<\EOF
+#define HAVE_SMALLGMP 1
+EOF
+
+    NEED_LIBS="-lsmallgmp ${NEED_LIBS}"
+  else
+    echo "$ac_t""none" 1>&6
+    { echo "configure: error: can not build with smallgmp" 1>&2; exit 1; }
+  fi
+fi
+
+#
+echo $ac_n "checking whether to have MP""... $ac_c" 1>&6
+echo "configure:4679: checking whether to have MP" >&5
+if test "${with_MP}" != yes && test "${with_MP}" != no; then
+  if (test "${will_have_gmp}" = yes) && \
+     (test "$ac_MP_ok" =  yes || test "$enable_MP" = yes); then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define HAVE_MPSR 1
+EOF
+
+    HAVE_MPSR=1
+    MP_LIBS="-lMPT -lMP ${MP_LIBS}"
+  else
+    echo "$ac_t""no" 1>&6
+  fi
+elif  test "${with_MP}" = yes; then
+  if (test "${will_have_gmp}" = yes) && \
+     (test "$ac_MP_ok" =  yes || test "$enable_MP" = yes); then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define HAVE_MPSR 1
+EOF
+
+    HAVE_MPSR=1
+    MP_LIBS="-lMPT -lMP ${MP_LIBS}"
+  else
+    echo "$ac_t""no" 1>&6
+    { echo "configure: error: can not build with MP" 1>&2; exit 1; }
+  fi
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking whether to have NTL""... $ac_c" 1>&6
+echo "configure:4714: checking whether to have NTL" >&5
+if test "${with_NTL}" = yes ; then
+  echo "$ac_t""yes" 1>&6
+  NEED_LIBS="-lntl ${NEED_LIBS}"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking whether to have factory""... $ac_c" 1>&6
+echo "configure:4723: checking whether to have factory" >&5
+if test "${with_factory}" != yes && test "${with_factory}" != no; then
+  if test "$ac_factory_ok" =  yes || test "$enable_factory" = yes; then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define HAVE_FACTORY 1
+EOF
+
+    will_have_factory=yes
+    NEED_LIBS="-lsingcf ${NEED_LIBS}"
+  else
+    echo "$ac_t""no" 1>&6
+  fi
+elif  test "${with_factory}" = yes; then
+  if test "$ac_factory_ok" =  yes || test "$enable_factory" = yes; then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define HAVE_FACTORY 1
+EOF
+
+    will_have_factory=yes
+    NEED_LIBS="-lsingcf ${NEED_LIBS}"
+  else
+    echo "$ac_t""no" 1>&6
+    { echo "configure: error: can not build with factory" 1>&2; exit 1; }
+  fi
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking whether to have libfac""... $ac_c" 1>&6
+echo "configure:4754: checking whether to have libfac" >&5
+if test "${with_libfac}" != yes && test "${with_libfac}" != no; then
+  if (test "${will_have_factory}" = yes) && \
+     (test "$ac_libfac_ok" =  yes || test "$enable_libfac" = yes); then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define HAVE_LIBFAC_P 1
+EOF
+
+    NEED_LIBS="-lsingfac ${NEED_LIBS}"
+  else
+    echo "$ac_t""no" 1>&6
+  fi
+elif  test "${with_libfac}" = yes; then
+  if (test "${will_have_factory}" = yes) && \
+     (test "$ac_libfac_ok" =  yes || test "$enable_libfac" = yes); then
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define HAVE_LIBFAC_P 1
+EOF
+
+    NEED_LIBS="-lsingfac ${NEED_LIBS}"
+  else
+    echo "$ac_t""no" 1>&6
+    { echo "configure: error: can not build with libfac" 1>&2; exit 1; }
+  fi
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+
+echo $ac_n "checking whether to have dbm links""... $ac_c" 1>&6
+echo "configure:4788: checking whether to have dbm links" >&5
+if test "$with_dbm" != no; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_DBM 1
+EOF
+
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking whether to have namespaces""... $ac_c" 1>&6
+echo "configure:4800: checking whether to have namespaces" >&5
+if test "$with_namespaces" != no; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define HAVE_NS 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking whether to have dynamic modules""... $ac_c" 1>&6
+echo "configure:4812: checking whether to have dynamic modules" >&5
+if test "$with_dynamic_modules" = no || test "$ac_have_dl" != yes; then
+  echo "$ac_t""no" 1>&6
+else
+  cat >> confdefs.h <<\EOF
+#define HAVE_DYNAMIC_LOADING 1
+EOF
+
+  echo "$ac_t""yes" 1>&6
+fi
+
+echo $ac_n "checking whether to have dynamic kernel""... $ac_c" 1>&6
+echo "configure:4824: checking whether to have dynamic kernel" >&5
+if test "$with_dynamic_kernel" != no && test "$ac_lib_dl" = yes; then
+  DL_KERNEL=1
+  
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking whether to have Plural""... $ac_c" 1>&6
+echo "configure:4834: checking whether to have Plural" >&5
+if test "$with_Plural" != yes && test "$enable_Plural" != yes; then
+  echo "$ac_t""no" 1>&6
+else
+  cat >> confdefs.h <<\EOF
+#define HAVE_PLURAL 1
+EOF
+
+  echo "$ac_t""yes" 1>&6
+fi
+
+
+OUTPUT_MAKEFILES=Makefile
+
+if test "$ac_cv_singuname" = "ix86-Win"; then
+  OUTPUT_MAKEFILES="${OUTPUT_MAKEFILES} Singular.rc"
+fi
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "${OUTPUT_MAKEFILES} mod2.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@SINGUNAME@%$SINGUNAME%g
+s%@EXEC_EXT@%$EXEC_EXT%g
+s%@SING_UNAME@%$SING_UNAME%g
+s%@SINGULAR_VERSION@%$SINGULAR_VERSION%g
+s%@VERSION_DATE@%$VERSION_DATE%g
+s%@SINGULAR_MAJOR_VERSION@%$SINGULAR_MAJOR_VERSION%g
+s%@SINGULAR_MINOR_VERSION@%$SINGULAR_MINOR_VERSION%g
+s%@SINGULAR_SUB_VERSION@%$SINGULAR_SUB_VERSION%g
+s%@CC@%$CC%g
+s%@CPP@%$CPP%g
+s%@CXX@%$CXX%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PIPE@%$PIPE%g
+s%@CXXTEMPLFLAGS@%$CXXTEMPLFLAGS%g
+s%@CXXNOOPTFLAGS@%$CXXNOOPTFLAGS%g
+s%@STATIC_LDFLAGS@%$STATIC_LDFLAGS%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@SINGULAR@%$SINGULAR%g
+s%@LEX@%$LEX%g
+s%@BISON@%$BISON%g
+s%@LN_S@%$LN_S%g
+s%@PERL@%$PERL%g
+s%@LD_DYN_FLAGS@%$LD_DYN_FLAGS%g
+s%@SFLAGS@%$SFLAGS%g
+s%@SLDFLAGS@%$SLDFLAGS%g
+s%@LD@%$LD%g
+s%@ALLOCA@%$ALLOCA%g
+s%@CXXCPP@%$CXXCPP%g
+s%@HAVE_MPSR@%$HAVE_MPSR%g
+s%@MP_LIBS@%$MP_LIBS%g
+s%@NEED_LIBS@%$NEED_LIBS%g
+s%@DL_KERNEL@%$DL_KERNEL%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"${OUTPUT_MAKEFILES}"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+  case "$ac_given_INSTALL" in
+  [/$]*) INSTALL="$ac_given_INSTALL" ;;
+  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+  esac
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ 	]*\)#\([ 	]*define[ 	][ 	]*\)'
+ac_dB='\([ 	][ 	]*\)[^ 	]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_uB='\([ 	]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+  CONFIG_HEADERS="mod2.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  echo creating $ac_file
+
+  rm -f conftest.frag conftest.in conftest.out
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h.  And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ 	]*#[ 	]*undef[ 	][ 	]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+  ac_lines=`grep -c . conftest.vals`
+  # grep -c gives empty output for an empty file on some AIX systems.
+  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+  # Write a limited-size here document to conftest.frag.
+  echo '  cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+  echo 'CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+  rm -f conftest.vals
+  mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+  rm -f conftest.frag conftest.h
+  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
+  cat conftest.in >> conftest.h
+  rm -f conftest.in
+  if cmp -s $ac_file conftest.h 2>/dev/null; then
+    echo "$ac_file is unchanged"
+    rm -f conftest.h
+  else
+    # Remove last slash and all that follows it.  Not all systems have dirname.
+      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+      # The file is in a subdirectory.
+      test ! -d "$ac_dir" && mkdir "$ac_dir"
+    fi
+    rm -f $ac_file
+    mv conftest.h $ac_file
+  fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+\
+ if test "$CONFIG_HEADERS"; then echo timestamp > stamp-h; fi
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
Index: kernel/configure.in
===================================================================
--- kernel/configure.in	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/configure.in	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,880 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(mmalloc.cc)
+AC_CONFIG_HEADER(mod2.h)
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl determine singuname
+dnl
+
+AC_MSG_CHECKING(uname for singular)
+AC_CACHE_VAL(ac_cv_singuname,
+ac_cv_singuname="unknown"
+if test -r "singuname.sh"; then
+  if (/bin/sh singuname.sh >/dev/null 2>&1) then
+    ac_cv_singuname=`/bin/sh singuname.sh`
+  fi
+fi
+if test "$ac_cv_singuname" = unknown && test -r "../singuname.sh"; then
+  if (/bin/sh ../singuname.sh >/dev/null 2>&1) then
+    ac_cv_singuname=`/bin/sh ../singuname.sh`
+  fi
+fi
+)
+AC_MSG_RESULT($ac_cv_singuname)
+if test "$ac_cv_singuname" = unknown; then
+  AC_MSG_WARN(Unknown architecture: Check singuname.sh)
+  ac_cv_singuname="unknown"
+fi
+AC_DEFINE_UNQUOTED(S_UNAME, "$ac_cv_singuname")
+SINGUNAME=$ac_cv_singuname
+AC_SUBST(SINGUNAME)
+
+if test "$ac_cv_singuname" = ix86-Win; then
+  EXEC_EXT=".exe"
+fi
+AC_SUBST(EXEC_EXT)
+
+SING_UNAME=`echo $SINGUNAME | tr '-' '_' `
+AC_SUBST(SING_UNAME)
+
+# stupid Win programs do not like dots in their pathnames
+VERSION_SEP="-"
+
+dnl llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl version stuff -- should be set in ../configure.in
+dnl
+dnl here are some defaults
+
+SINGULAR_MAJOR_VERSION=${SINGULAR_MAJOR_VERSION:-2}
+SINGULAR_MINOR_VERSION=${SINGULAR_MINOR_VERSION:-1}
+SINGULAR_SUB_VERSION=${SINGULAR_SUB_VERSION:-2}
+SINGULAR_VERSION="${SINGULAR_VERSION:-$SINGULAR_MAJOR_VERSION${VERSION_SEP}$SINGULAR_MINOR_VERSION${VERSION_SEP}$SINGULAR_SUB_VERSION}"
+VERSION_DATE=${VERSION_DATE:-"July 2003"}
+
+dnl pass them on into the Makefiles
+AC_SUBST(SINGULAR_VERSION)
+AC_SUBST(VERSION_DATE)
+AC_SUBST(SINGULAR_MAJOR_VERSION)
+AC_SUBST(SINGULAR_MINOR_VERSION)
+AC_SUBST(SINGULAR_SUB_VERSION)
+AC_DEFINE_UNQUOTED(SINGULAR_MAJOR_VERSION, ${SINGULAR_MAJOR_VERSION})
+AC_DEFINE_UNQUOTED(SINGULAR_MINOR_VERSION, ${SINGULAR_MINOR_VERSION})
+AC_DEFINE_UNQUOTED(SINGULAR_SUB_VERSION, ${SINGULAR_SUB_VERSION})
+AC_DEFINE_UNQUOTED(S_VERSION1, "${SINGULAR_MAJOR_VERSION}${VERSION_SEP}${SINGULAR_MINOR_VERSION}${VERSION_SEP}${SINGULAR_SUB_VERSION}")
+AC_DEFINE_UNQUOTED(S_VERSION2, "${VERSION_DATE}")
+AC_DEFINE_UNQUOTED(SINGULAR_SUB_VERSION, ${SINGULAR_SUB_VERSION})
+
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl compiler stuff
+dnl is needed to check for libs and headers, later on
+dnl
+dnl we do not want to have "-g -O" for CFLAGS
+if test "${CXXFLAGS+set}" != set; then
+  ac_cxxflags_set=no
+  CXXFLAGS="-O"
+fi
+if test "${CFLAGS+set}" != set; then
+  CFLAGS="-O"
+  ac_cflags_set=no
+fi
+
+# check whether CXX was set by user as env variable
+if test "${CXX+set}" != set; then
+  ac_cxx_set=no
+else
+  ac_cxx_set=yes
+fi
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_CXX
+AC_PROG_INSTALL
+AC_AIX
+
+# test for gcc-version: gcc2: prefer CC=gcc, CXX=gcc
+#                       gcc3:        CC=gcc  CXX=g++
+#                       other:       CC=cc   CXX=c++
+AC_MSG_CHECKING(gcc version)
+AC_CACHE_VAL(ac_cv_c_cpp,
+ac_cv_c_cp="unknown"
+if test -r "gccversion.sh"; then
+  ac_cv_c_cpp=`/bin/sh gccversion.sh`
+fi
+)
+AC_MSG_RESULT($ac_cv_c_cpp)
+
+# we prefer using gcc for compiling C++ files, provided the user did
+# not overwrite it explicitely
+if test "${GXX}" = yes && test "${ac_cxx_set}" = no; then
+  if test "${ac_cv_c_cpp}" = gcc2; then
+    CXX=gcc
+  elif test "${ac_cv_c_cpp}" = gcc3; then
+    CXX=g++
+  fi
+  temp_cflags=${CXXFLAGS}
+  AC_LANG_SAVE
+  AC_LANG_CPLUSPLUS
+  # check whether gcc accepts --no-rtti
+  AC_MSG_CHECKING(whether gcc accepts --no-rtti)
+  CXXFLAGS="${CXXFLAGS} --no-rtti"
+  AC_CACHE_VAL(ac_cv_cxx_have_rtti,
+    AC_TRY_COMPILE(,,ac_cv_cxx_have_rtti=yes,ac_cv_cxx_have_rtti=no)
+  )
+  AC_MSG_RESULT(${ac_cv_cxx_have_rtti})
+  if test "${ac_cv_cxx_have_rtti}" != yes; then
+  CXXFLAGS=$temp_flags
+  else
+  CXX="${CXX} --no-rtti"
+  fi
+
+# check whether gcc accepts --no-exceptions
+  AC_MSG_CHECKING(whether gcc accepts --no-exceptions)
+  CXXFLAGS="${CXXFLAGS} --no-exceptions"
+  AC_CACHE_VAL(ac_cv_cxx_have_exceptions,
+    AC_TRY_LINK(,,ac_cv_cxx_have_exceptions=yes,ac_cv_cxx_have_exceptions=no)
+  )
+  AC_MSG_RESULT(${ac_cv_cxx_have_exceptions})
+  if test "${ac_cv_cxx_have_exceptions}" != yes; then
+  CXXFLAGS=$temp_flags
+  else
+  CXX="${CXX} --no-exceptions"
+  fi
+
+  AC_LANG_RESTORE
+  CXXFLAGS=$temp_flags
+
+fi
+
+# check whether the compiler accepts -pipe
+AC_MSG_CHECKING(whether compiler accepts -pipe)
+temp_cflags=${CFLAGS}
+CFLAGS="${CFLAGS} -pipe"
+AC_CACHE_VAL(ac_cv_cxx_have_pipe,
+AC_TRY_COMPILE(,,ac_cv_cxx_have_pipe=yes,ac_cv_cxx_have_pipe=no)
+)
+AC_MSG_RESULT(${ac_cv_cxx_have_pipe})
+CFLAGS=${temp_cflags}
+if test "${ac_cv_cxx_have_pipe}" != yes; then
+  PIPE=
+else
+  PIPE="-pipe"
+fi
+AC_SUBST(PIPE)
+
+# Customize CFLAGS
+AC_MSG_CHECKING(whether _AIX is defined)
+AC_CACHE_VAL(ac_cv_is_aix,
+AC_EGREP_CPP(yes,
+[#ifdef _AIX
+    yes
+#endif
+], ac_cv_is_aix=yes, ac_cv_is_aix=no, 1))
+if test "$ac_cv_is_aix" = yes; then
+  AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+fi
+
+# we know best when compiling with gcc
+if test "${GXX}" = yes; then
+  if test "$ac_cxxflags_set" = no; then
+    CXXFLAGS="-O3 -w -fomit-frame-pointer"
+  fi
+  CXXTEMPLFLAGS="-fno-implicit-templates"
+  if test "$ac_cv_is_aix" = yes; then
+    CXXNOOPTFLAGS="-w"
+  else
+    CXXNOOPTFLAGS=$CXXFLAGS
+  fi
+  STATIC_LDFLAGS="-static"
+else
+  CXXTEMPFLAGS=""
+  CXXNOOPTFLAGS=$CXXFLAGS
+  STATIC_LDFLAGS=""
+fi
+AC_SUBST(CXXTEMPLFLAGS)
+AC_SUBST(CXXNOOPTFLAGS)
+AC_SUBST(STATIC_LDFLAGS)
+
+if test "${GCC}" = yes && test "$ac_cflags_set" = no ; then
+  CFLAGS="-O3 -w -fomit-frame-pointer"
+fi
+
+AC_PROG_MAKE_SET
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl path stuff
+dnl
+AC_PREFIX_DEFAULT(`pwd`/..)
+
+dnl set exec_prefix, bindir, libdir, includedir to some sensible values
+dnl if they are not yet already set
+
+# expand prefix
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+if test "${with_rootdir+set}" != set; then
+  AC_DEFINE_UNQUOTED(S_ROOT_DIR, "${prefix}")
+else
+  AC_DEFINE_UNQUOTED(S_ROOT_DIR, "${with_rootdir}")
+fi
+
+# expand exec_prefixad
+if test "x$exec_prefix" = xNONE; then
+ exec_prefix=${prefix}/${ac_cv_singuname}
+fi
+
+# expand bindir
+test "x$bindir" = 'x${exec_prefix}/bin' && bindir="${exec_prefix}"
+SINGULAR=${SINGULAR:-$bindir/Singular-$SINGULAR_MAJOR_VERSION${VERSION_SEP}$SINGULAR_MINOR_VERSION${VERSION_SEP}$SINGULAR_SUB_VERSION}
+AC_SUBST(SINGULAR)
+AC_DEFINE_UNQUOTED(S_BIN_DIR, "${bindir}")
+
+# expand libdir
+test "x$libdir" = 'x${exec_prefix}/lib'&& libdir="${exec_prefix}/lib"
+
+# expand includedir
+test "x$includedir" = 'x${prefix}/include' && includedir="${exec_prefix}/include"
+
+# add to -I to CPPFLAGS and and -L to LDFLAGS, just to be sure
+if test "$ac_cv_c_cpp" = gcc3 ; then
+  LDFLAGS="-L${libdir} ${LDFLAGS}"
+  CPPFLAGS="-I${includedir} ${CPPFLAGS}"
+else
+  LDFLAGS="-L${libdir} ${LDFLAGS} -L/usr/local/lib"
+  CPPFLAGS="-I${includedir} ${CPPFLAGS} -I/usr/local/include"
+fi
+
+# this is a work-around to include the right term.h
+if test "$ac_cv_singuname" = SunOS-5; then
+CPPFLAGS="-I/usr/xpg4/include ${CPPFLAGS}"
+fi
+
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl Checks for programs.
+dnl
+
+# lex
+if test "${with_lex+set}" != set; then
+  AC_MSG_CHECKING(for flex)
+  changequote(<<,>>)dnl
+  cmd="egrep [2-9]\.[5-9]"
+  changequote([,])dnl
+  AC_CACHE_VAL(ac_cv_prog_flex,
+  if (flex --version >/dev/null 2>&1)
+    then
+    if (flex --version | $cmd >/dev/null 2>&1 )
+    then
+	ac_cv_prog_flex=flex
+    fi
+  fi
+  )
+  dnl changequote([,])dnl
+  if test "${ac_cv_prog_flex+set}" = set; then
+    AC_MSG_RESULT(flex)
+    LEX=flex
+    AC_SUBST(LEX)
+  else
+    AC_MSG_ERROR(can not find flex with version greater 2.4)
+  fi
+elif test "${with_lex}" = no; then
+  AC_MSG_WARN(building without lex -- make might fail)
+else
+  unset LEX
+  unset ac_cv_prog_LEX
+  AC_CHECK_PROGS(LEX, ${with_lex})
+  if test "x${LEX}" = x; then
+    AC_MSG_WARN(building without lex -- make might fail)
+  fi
+fi
+
+# bison
+AC_CHECK_PROGS(BISON, bison)
+if test "${BISON+set}" != set; then
+  AC_MSG_WARN(did not find bison -- make might fail)
+fi
+
+# ln -s
+AC_PROG_LN_S
+
+AC_CHECK_PROGS(PERL, perl5 perl)
+
+dnl llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl check for general libraries, header files, typedefs, etc
+dnl
+# lib checks
+# under cygwin, we should not explicitly link with -lm, except for
+# it really is the last thing to link with
+if test "$ac_cv_singuname" != ix86-Win; then
+AC_CHECK_LIB(m, atof)
+fi
+SAVE_LIBS=${LIBS}
+LIBS=
+
+dnl I'm not sure what they are for
+dnl AC_CHECK_LIB(bsd, socket)
+dnl AC_CHECK_LIB(socket, listen)
+dnl AC_CHECK_LIB(nsl, gethostbyname)
+dnl AC_CHECK_LIB(ucb, index)
+dnl MP_LIBS=${LIBS}
+# check for dl lib
+case "$ac_cv_singuname" in
+	HPUX*)
+	  AC_CHECK_LIB(dld, shl_load)
+	  if test "$ac_cv_lib_dld_shl_load" = yes; then
+         	LD_DYN_FLAGS="-ldld -Xlinker -E"
+	  	SFLAGS="-fpic -fPIC -DPIC"
+	  	SLDFLAGS="-fPIC -DPIC -shared"
+		LD=gcc
+		ac_lib_dl=yes
+	  fi
+	;;
+	*Linux*)
+	  AC_CHECK_LIB(dl, dlopen)
+          if test "$ac_cv_lib_dl_dlopen" = yes; then
+	  	LD_DYN_FLAGS="-ldl -rdynamic"
+	  	SFLAGS="-fpic -DPIC"
+	  	SLDFLAGS=-shared
+		LD=ld
+	        ac_lib_dl=yes
+	  fi
+	;;
+        IRIX-6)
+          LD_DYN_FLAGS="-lc"
+	  SFLAGS="-fPIC -DPIC"
+	  SLDFLAGS="-w -no_unresolved -_SYSTYPE_SVR4 -n32 -shared"
+          LD=ld
+	  ac_lib_dl=yes
+        ;;
+	SunOS-5)
+	  AC_CHECK_LIB(dl, dlopen)
+          if test "$ac_cv_lib_dl_dlopen" = yes; then
+	  	LD_DYN_FLAGS="-ldl -Xlinker -E"
+	  	SFLAGS="-fpic -DPIC"
+	  	SLDFLAGS=-shared
+                LD=ld
+	        ac_lib_dl=yes
+	  fi
+	;;
+esac
+AC_SUBST(LD_DYN_FLAGS)
+AC_SUBST(SFLAGS)
+AC_SUBST(SLDFLAGS)
+AC_SUBST(LD)
+LIBS=${SAVE_LIBS}
+
+
+# heder file checks
+AC_HEADER_STDC
+AC_CHECK_HEADERS(limits.h unistd.h,,
+  AC_MSG_ERROR(Can not compile without limits.h unistd.h))
+
+AC_CHECK_HEADERS(sys/file.h sys/ioctl.h sys/time.h sys/times.h sys/types.h \
+ sys/stat.h fcntl.h sys/param.h pwd.h asm/sigcontext.h pwd.h termcap.h \
+ termios.h term.h readline/readline.h)
+
+# typedefs, structures
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_SIZE_T
+AC_STRUCT_TM
+AC_HEADER_TIME
+
+# library functions.
+AC_FUNC_ALLOCA
+AC_PROG_GCC_TRADITIONAL
+AC_FUNC_MMAP
+AC_TYPE_SIGNAL
+AC_FUNC_VPRINTF
+AC_SEARCH_LIBS(setenv, bsd)
+AC_CHECK_FUNCS(gettimeofday atexit bcopy getcwd getwd vsnprintf readlink \
+ sleep usleep getpwnam popen setenv)
+
+
+dnl llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl Find out more about particularity of the system
+dnl
+
+# arithmetic shifts
+AC_MSG_CHECKING(whether your machine has correct arithmetic shifts)
+AC_CACHE_VAL(ac_cv_shift, AC_TRY_RUN(
+  [ int main() { if (-2 >> 1 == -1) exit(0); else exit(1); } ],
+   ac_cv_shift=yes,
+   ac_cv_shift=no,
+   if test "$ac_c_cross_dos" = yes; then
+     ac_cv_shift=yes;
+   else
+     AC_MSG_RESULT(no)
+     AC_MSG_ERROR(cross compilation without default value)
+   fi))
+
+if test "$ac_cv_shift" = yes; then
+  AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+  AC_MSG_ERROR(need  -2 >> 1 == -1)
+fi
+
+
+# check for a peculiar constructor initialization
+AC_MSG_CHECKING(whether explicit C++ constructor calls are allowed)
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+AC_CACHE_VAL(ac_cv_explicit_const,AC_TRY_COMPILE(,
+  class testclass
+  {
+  public:
+    int value;
+    testclass() : value(0) {}
+    testclass( int i ) : value(i) {}
+    ~testclass() { value = 0; }
+  };
+
+  testclass ptr;
+  ptr.testclass(1);
+, ac_cv_explicit_const=yes, ac_cv_explicit_const=no))
+AC_LANG_RESTORE
+AC_MSG_RESULT($ac_cv_explicit_const)
+if test "$ac_cv_explicit_const" = yes; then
+  AC_DEFINE(HAVE_EXPLICIT_CONSTR)
+fi
+
+# sprintf returns number of printed chars
+AC_MSG_CHECKING(whether vsprintf returns number of printed chars)
+AC_CACHE_VAL(ac_cv_returns_n_of_chars, AC_TRY_RUN(
+ [#include <stdio.h>
+ main() { char *str=(char*)malloc(20); if (((int) sprintf(str,"123456789")) == 9) exit(0); else exit(1); }],
+   ac_cv_returns_n_of_chars=yes,
+   ac_cv_returns_n_of_chars=no,
+   ac_cv_returns_n_of_chars=no))
+if test "$ac_cv_returns_n_of_chars" = yes; then
+  AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+  AC_DEFINE(BSD_SPRINTF)
+fi
+
+# determine ALIGN_8
+AC_CHECK_SIZEOF(char,1)
+AC_CHECK_SIZEOF(short,2)
+AC_CHECK_SIZEOF(int,4)
+AC_CHECK_SIZEOF(long,4)
+AC_CHECK_SIZEOF(void*,4)
+AC_CHECK_SIZEOF(double, 8)
+AC_C_BIGENDIAN
+if test "$ac_cv_sizeof_int" != 4; then
+  AC_MSG_ERROR(need int to be four bytes long)
+fi
+if test "$ac_cv_sizeof_long" != "$ac_cv_sizeof_voidp"; then
+  AC_MSG_ERROR(need equal sizes for long and void*)
+fi
+if test "$ac_cv_sizeof_double" != 8; then
+  AC_MSG_ERROR(need double to b 8 bytes long)
+fi
+if test "$ac_cv_sizeof_voidp" != 4 && test "$ac_cv_sizeof_voidp" != 8; then
+  AC_MSG_ERROR(need void* to be 4 or 8 bytes long)
+fi
+
+dnl lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl help for configure
+dnl
+AC_ARG_WITH(
+  rootdir,
+  [  --with-rootdir=DIR      use DIR ass compiled-in root directory
+                             (default is PREFIX)])
+AC_ARG_WITH(
+  lex,
+  [  --with-lex=[LEX,no]     uses LEX as lex program, default is flex])
+AC_ARG_WITH(
+  readline,
+  [  --with-readline=[dynamic,static,no]          
+                          do use dynamic/static/no readline for fancy display])
+AC_ARG_WITH(
+  MP,
+  [  --without-MP            do not use MP (no MP links)])
+AC_ARG_WITH(
+  dbm,
+  [  --without-dbm           do not use dbm (no DBM links)])
+AC_ARG_WITH(
+  factory,
+  [  --without-factory       do not use factory (no poly factorization)])
+AC_ARG_WITH(
+  libfac,
+  [  --without-libfac        do not use libfac (no primary decompositions)])
+AC_ARG_WITH(
+  namespaces,
+  [  --with-namespaces       do compile namespace support])
+AC_ARG_WITH(
+  dl,
+  [  --without-dl            do not use dynamic linking, modules, and kernel])
+AC_ARG_WITH(
+  dynamic-modules,
+  [  --with-dynamic-modules  do compile with dynamic modules support]) 
+AC_ARG_WITH(
+  dynamic-kernel,
+  [  --without-dynamic-kernel               
+                          do not compile with dynamic kernel parts])
+AC_ARG_WITH(apint,
+  [  --with-apint=PACKAGE    use PACKAGE for arbitary integer arithmetic])
+AC_ARG_WITH(
+  Plural,
+  [  --with-Plural           do compile with Plural support])
+AC_ARG_WITH(
+  NTL,
+  [  --with-NTL              build for use with NTL.],
+  ,
+  with_NTL=yes)
+
+dnl llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl check for packages we need
+dnl for gmp, MP, factory and libfac, we built them in, even if the libs
+dnl and headers were not found under the condition that the respective
+dnl  --enable argument was given
+dnl
+
+
+AC_MSG_CHECKING(whether to use dynamic linking)
+if test "$with_dl" != no && test "$ac_lib_dl" = yes; then
+  AC_DEFINE(HAVE_DL)
+  ac_have_dl=yes
+  AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+fi
+
+AC_CHECK_LIB(ncurses,tgetent,,\
+ AC_CHECK_LIB(curses,tgetent,,\
+  AC_CHECK_LIB(termcap,tgetent)))
+
+# readline
+if test "$with_readline" = dynamic && test "$ac_have_dl" != yes; then
+  AC_MSG_WARN(can not build dynamic readline without dynamic linking)
+  with_readline=static
+fi
+
+
+if test "$with_readline" != dynamic && test "$with_readline" != no; then
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+   AC_CHECK_LIB(readline, rl_abort)
+   AC_CHECK_HEADERS(readline/readline.h readline/history.h)
+   if test "$ac_cv_lib_readline_rl_abort" = yes && \
+      test "$ac_cv_header_readline_readline_h" = yes; then
+     AC_MSG_CHECKING(whether readline.h is ok)
+     AC_CACHE_VAL(ac_cv_header_readline_readline_h_ok,
+     AC_TRY_LINK(
+#include<unistd.h>
+#include<stdio.h>
+#include<readline/readline.h>
+#ifdef HAVE_READLINE_HISTORY_H
+#include<readline/history.h>
+#endif
+,
+,
+ac_cv_header_readline_readline_h_ok="yes",
+ac_cv_header_readline_readline_h_ok="no",
+))
+    AC_MSG_RESULT($ac_cv_header_readline_readline_h_ok)
+    if test "$ac_cv_header_readline_readline_h_ok" != yes; then
+#not ok -- try once more with explicitly declaring everything
+      AC_MSG_CHECKING(whether or not we nevertheless can use readline)
+      AC_CACHE_VAL(ac_cv_have_readline,
+      AC_TRY_LINK(
+#include <stdio.h>
+extern "C"
+{
+extern char * rl_readline_name;
+extern char *rl_line_buffer;
+char *filename_completion_function();
+typedef char **CPPFunction ();
+extern char ** completion_matches ();
+extern CPPFunction * rl_attempted_completion_function;
+extern FILE * rl_outstream;
+char * readline ();
+void add_history ();
+int write_history ();
+int read_history();
+}
+#ifndef NULL
+#define NULL 0
+#endif
+,
+rl_readline_name=NULL;
+*rl_line_buffer=1;
+completion_matches(NULL, filename_completion_function);
+rl_attempted_completion_function = (CPPFunction *) NULL;
+rl_outstream=NULL;
+readline(NULL);
+add_history(NULL);
+read_history(NULL);
+write_history(NULL);
+,
+ac_cv_have_readline="yes"
+,
+ac_cv_have_readline="no"
+))
+      AC_MSG_RESULT($ac_cv_have_readline)
+    else
+      AC_DEFINE(READLINE_READLINE_H_OK)
+      ac_cv_have_readline="yes"
+    fi
+  fi
+  if test "$ac_cv_have_readline" = yes; then
+    AC_DEFINE(HAVE_READLINE)
+  fi
+AC_LANG_RESTORE
+fi
+
+AC_MSG_CHECKING(which readline to use)
+if test "$ac_cv_with_readline" = dynamic; then
+  AC_MSG_RESULT(dynamic)
+  AC_DEFINE(HAVE_DYN_RL)
+elif test "$ac_cv_have_readline" = yes; then
+  AC_MSG_RESULT(static)
+elif test "$ac_cv_singuname" = PowerMacintosh-darwin; then
+  AC_MSG_ERROR(building without readline impossible on PowerMacintosh-darwin)
+else
+  AC_MSG_RESULT(none)
+  AC_MSG_WARN(building without readline: disabling fancy display)
+fi
+  
+NEED_LIBS=$LIBS
+
+# gmp, smallgmp, MP, MPT, factory, libfac
+AC_CHECK_LIB(gmp, main)
+if test "ac_cv_lib_gmp_main" = yes && test "$with-apint" = smallgmp; then
+  LIBS=${NEED_LIBS}
+fi
+AC_CHECK_LIB(smallgmp, main)
+SAVE_LIBS=$LIBS
+AC_CHECK_LIB(MP, IMP_PutGmpInt,,,$MP_LIBS)
+AC_CHECK_LIB(MPT, MPT_GetTree,,,$MP_LIBS)
+LIBS=$SAVE_LIBS
+AC_CHECK_LIB(singcf, atof)
+AC_CHECK_LIB(singfac, atof)
+AC_CHECK_LIB(omalloc, omTestAddr)
+AC_CHECK_LIB(omalloc_ndebug, main)
+AC_CHECK_LIB(ntl,main)
+
+AC_CHECK_HEADERS(gmp.h smallgmp.h MP.h  MPT.h factory.h factor.h omalloc.h \
+ omalloc.c)
+
+if test "$ac_cv_lib_gmp_main" = yes && \
+ test "$ac_cv_header_gmp_h" = yes; then
+    ac_gmp_ok=yes
+fi
+
+if test "$ac_cv_lib_smallgmp_main" = yes && \
+ test "$ac_cv_header_smallgmp_h" = yes && \
+ test "$ac_cv_header_gmp_h" = yes; then
+    ac_smallgmp_ok=yes
+fi
+
+if test "$ac_cv_lib_MP_IMP_PutGmpInt" = yes && \
+ test "$ac_cv_lib_MPT_MPT_GetTree" && \
+ test "$ac_cv_header_MP_h" = yes && \
+ test "$ac_cv_header_MPT_h" = yes; then
+  ac_MP_ok=yes
+fi
+
+if test "$ac_cv_lib_singcf_atof" = yes && \
+ test "$ac_cv_header_factory_h" = yes; then
+  ac_factory_ok=yes
+fi
+
+if test "$ac_cv_lib_singfac_atof" = yes && \
+ test "$ac_cv_header_factor_h" = yes; then
+  ac_libfac_ok=yes
+fi
+
+if test "$ac_cv_lib_omalloc_omTestAddr" = yes && \
+   test "$ac_cv_lib_omalloc_ndebug_main" = yes && \
+   test "$ac_cv_header_omalloc_c" = yes && \
+   test "$ac_cv_header_omalloc_h" = yes; then
+  ac_cv_omalloc_ok=yes
+fi
+
+if test "$ac_cv_lib_ntl_main" = yes; then
+  ac_cv_ntl_ok=yes
+fi
+
+# evaluate results
+dnl llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+dnl make sure that omalloc is there
+dnl 
+if test "$ac_cv_omalloc_ok" != yes && test "$enable_omalloc" != yes; then
+  AC_MSG_ERROR(can not build without omalloc)
+fi
+
+AC_MSG_CHECKING(which apint package to use)
+if test "${with_apint}" != gmp && test "${with_apint}" != smallgmp; then
+  if test "$ac_gmp_ok" = yes || test "$enable_gmp" = yes; then
+    AC_MSG_RESULT(gmp)
+    will_have_gmp=yes
+    NEED_LIBS="-lgmp ${NEED_LIBS}"
+  elif test "ac_gmp_smallgmp_ok" = yes || test "$enable_smallgmp" = "yes"; then
+    AC_MSG_RESULT(smallgmp)
+    AC_DEFINE(HAVE_SMALLGMP)
+    NEED_LIBS="-lsmallgmp ${NEED_LIBS}"
+  else
+    AC_MSG_RESULT(none)
+    AC_MSG_ERROR(can not build without gmp or smallgmp)
+  fi
+elif test "${with_apint}" = gmp; then
+  if test "$ac_gmp_ok" = yes || test "$enable_gmp" = yes; then
+    AC_MSG_RESULT(gmp)
+    will_have_gmp=yes
+    NEED_LIBS="-lgmp ${NEED_LIBS}"
+  else
+    AC_MSG_RESULT(none)
+    AC_MSG_ERROR(can not build with gmp)
+  fi
+else
+  if test "ac_gmp_smallgmp_ok" = yes || test "$enable_smallgmp" = "yes"; then
+    AC_MSG_RESULT(smallgmp)
+    AC_DEFINE(HAVE_SMALLGMP)
+    NEED_LIBS="-lsmallgmp ${NEED_LIBS}"
+  else
+    AC_MSG_RESULT(none)
+    AC_MSG_ERROR(can not build with smallgmp)
+  fi
+fi
+
+#
+AC_MSG_CHECKING(whether to have MP)
+if test "${with_MP}" != yes && test "${with_MP}" != no; then
+  if (test "${will_have_gmp}" = yes) && \
+     (test "$ac_MP_ok" =  yes || test "$enable_MP" = yes); then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(HAVE_MPSR)
+    HAVE_MPSR=1
+    MP_LIBS="-lMPT -lMP ${MP_LIBS}"
+  else
+    AC_MSG_RESULT(no)
+  fi
+elif  test "${with_MP}" = yes; then
+  if (test "${will_have_gmp}" = yes) && \
+     (test "$ac_MP_ok" =  yes || test "$enable_MP" = yes); then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(HAVE_MPSR)
+    HAVE_MPSR=1
+    MP_LIBS="-lMPT -lMP ${MP_LIBS}"
+  else
+    AC_MSG_RESULT(no)
+    AC_MSG_ERROR(can not build with MP)
+  fi
+else
+  AC_MSG_RESULT(no)
+fi
+AC_SUBST(HAVE_MPSR)
+AC_SUBST(MP_LIBS)
+
+AC_MSG_CHECKING(whether to have NTL)
+if test "${with_NTL}" = yes ; then
+  AC_MSG_RESULT(yes)
+  NEED_LIBS="-lntl ${NEED_LIBS}"
+else
+  AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(whether to have factory)
+if test "${with_factory}" != yes && test "${with_factory}" != no; then
+  if test "$ac_factory_ok" =  yes || test "$enable_factory" = yes; then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(HAVE_FACTORY)
+    will_have_factory=yes
+    NEED_LIBS="-lsingcf ${NEED_LIBS}"
+  else
+    AC_MSG_RESULT(no)
+  fi
+elif  test "${with_factory}" = yes; then
+  if test "$ac_factory_ok" =  yes || test "$enable_factory" = yes; then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(HAVE_FACTORY)
+    will_have_factory=yes
+    NEED_LIBS="-lsingcf ${NEED_LIBS}"
+  else
+    AC_MSG_RESULT(no)
+    AC_MSG_ERROR(can not build with factory)
+  fi
+else
+  AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(whether to have libfac)
+if test "${with_libfac}" != yes && test "${with_libfac}" != no; then
+  if (test "${will_have_factory}" = yes) && \
+     (test "$ac_libfac_ok" =  yes || test "$enable_libfac" = yes); then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(HAVE_LIBFAC_P)
+    NEED_LIBS="-lsingfac ${NEED_LIBS}"
+  else
+    AC_MSG_RESULT(no)
+  fi
+elif  test "${with_libfac}" = yes; then
+  if (test "${will_have_factory}" = yes) && \
+     (test "$ac_libfac_ok" =  yes || test "$enable_libfac" = yes); then
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(HAVE_LIBFAC_P)
+    NEED_LIBS="-lsingfac ${NEED_LIBS}"
+  else
+    AC_MSG_RESULT(no)
+    AC_MSG_ERROR(can not build with libfac)
+  fi
+else
+  AC_MSG_RESULT(no)
+fi
+
+
+AC_SUBST(NEED_LIBS)
+
+AC_MSG_CHECKING(whether to have dbm links)
+if test "$with_dbm" != no; then
+  AC_DEFINE(HAVE_DBM)
+  AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(whether to have namespaces)
+if test "$with_namespaces" != no; then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(HAVE_NS)
+else
+  AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(whether to have dynamic modules)
+if test "$with_dynamic_modules" = no || test "$ac_have_dl" != yes; then
+  AC_MSG_RESULT(no)
+else
+  AC_DEFINE(HAVE_DYNAMIC_LOADING)
+  AC_MSG_RESULT(yes)
+fi
+
+AC_MSG_CHECKING(whether to have dynamic kernel)
+if test "$with_dynamic_kernel" != no && test "$ac_lib_dl" = yes; then
+  DL_KERNEL=1
+  AC_SUBST(DL_KERNEL)
+  AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(whether to have Plural)
+if test "$with_Plural" != yes && test "$enable_Plural" != yes; then
+  AC_MSG_RESULT(no)
+else
+  AC_DEFINE(HAVE_PLURAL)
+  AC_MSG_RESULT(yes)
+fi
+
+
+OUTPUT_MAKEFILES=Makefile
+
+if test "$ac_cv_singuname" = "ix86-Win"; then
+  OUTPUT_MAKEFILES="${OUTPUT_MAKEFILES} Singular.rc"
+fi
+
+AC_OUTPUT(${OUTPUT_MAKEFILES}, \
+ if test "$CONFIG_HEADERS"; then echo timestamp > stamp-h; fi)
Index: kernel/dError.c
===================================================================
--- kernel/dError.c	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/dError.c	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,75 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    dError.c
+ *  Purpose: implementation for debug error handling
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 9/00
+ *  Version: $Id: dError.c,v 1.1.1.1 2003-10-06 12:15:51 Singular Exp $
+ *******************************************************************/
+#ifndef DERROR_C
+#define DERROR_C
+#include <stdarg.h>
+#include <stdio.h>
+#include "mod2.h"
+#include "distrib.h"
+#ifdef p_Procs_Static
+#include "version.h"
+#endif
+#ifdef HAVE_CONFIG_H
+#include "omalloc.h"
+#endif
+#ifdef MAKE_DISTRIBUTION
+#include "version.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" 
+{
+#endif
+
+int dReportError(const char* fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+#ifndef MAKE_DISTRIBUTION
+  fprintf(stderr, "\n// ***dError: ");
+  vfprintf(stderr, fmt, ap);
+#if 0
+    if !defined(OM_NDEBUG) && defined(HAVE_CONFIG_H)
+#endif
+#if  defined(HAVE_CONFIG_H)
+  fprintf(stderr, " occured at: \n");
+  omPrintCurrentBackTraceMax(stderr, 8);
+#endif
+  dErrorBreak();
+#else
+  fprintf(stderr, "\n// !!! YOU HAVE FOUND A BUG IN SINGULAR.");
+  fprintf(stderr, "// !!! Please, email the following output to singular@mathematik.uni-kl.de");
+  fprintf(stderr, "// !!! Singular Version: " S_UNAME S_VERSION1 " (%lu)\n",
+          feVersionId);
+  vfprintf(stderr, fmt, ap);
+#endif
+  return 0;
+}
+
+
+#ifndef MAKE_DISTRIBUTION
+// dummy procedure for setting a breakpoint
+// within the debugger
+void dErrorBreak()
+{}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+  
+
+
+  
+  
+  
Index: kernel/dError.h
===================================================================
--- kernel/dError.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/dError.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,29 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    dError.h
+ *  Purpose: declaration for debug error handling
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 9/00
+ *  Version: $Id: dError.h,v 1.1.1.1 2003-10-06 12:15:51 Singular Exp $
+ *******************************************************************/
+#ifndef DERROR_H
+#define DERROR_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+extern int dReportError(const char* fmt, ...);
+#define dReportBug(s) \
+  dReportError("Bug reported: %s\n occured at %s,%d\n", s, __FILE__, __LINE__)
+#endif
+
+// this is just a dummy procedure which is called after the error
+// has been reported. Within the debugger, set a breakpoint on this
+// proc.
+extern void dErrorBreak();
+#ifdef __cplusplus
+}
+#endif
Index: kernel/dbm_sl.h
===================================================================
--- kernel/dbm_sl.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/dbm_sl.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,16 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    dbm_sl.h
+ *  Purpose: declaration of sl_link routines for dbm
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *  Version: $Id: dbm_sl.h,v 1.1.1.1 2003-10-06 12:15:51 Singular Exp $
+ *******************************************************************/
+LINKAGE BOOLEAN dbOpen(si_link l, short flag);
+LINKAGE BOOLEAN dbWrite(si_link l, leftv v);
+LINKAGE leftv dbRead1(si_link l);
+LINKAGE leftv dbRead2(si_link l, leftv key);
+LINKAGE BOOLEAN dbClose(si_link l);
+
Index: kernel/distrib.h
===================================================================
--- kernel/distrib.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/distrib.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1 @@
+#undef MAKE_DISTRIBUTION
Index: kernel/eigenval.cc
===================================================================
--- kernel/eigenval.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/eigenval.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,400 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/* $Id: eigenval.cc,v 1.1.1.1 2003-10-06 12:15:51 Singular Exp $ */
+/*
+* ABSTRACT: eigenvalues of constant square matrices
+*/
+
+#include "mod2.h"
+
+#ifdef HAVE_EIGENVAL
+
+#include "febase.h"
+#include "tok.h"
+#include "ipid.h"
+#include "intvec.h"
+#include "numbers.h"
+#include "polys.h"
+#include "ideals.h"
+#include "lists.h"
+#include "matpol.h"
+#include "clapsing.h"
+#include "eigenval.h"
+
+
+matrix evSwap(matrix M,int i,int j)
+{
+  if(i==j)
+    return(M);
+
+  for(int k=1;k<=MATROWS(M);k++)
+  {
+    poly p=MATELEM(M,i,k);
+    MATELEM(M,i,k)=MATELEM(M,j,k);
+    MATELEM(M,j,k)=p;
+  }
+
+  for(int k=1;k<=MATCOLS(M);k++)
+  {
+    poly p=MATELEM(M,k,i);
+    MATELEM(M,k,i)=MATELEM(M,k,j);
+    MATELEM(M,k,j)=p;
+  }
+
+  return(M);
+}
+
+
+BOOLEAN evSwap(leftv res,leftv h)
+{
+  if(currRingHdl)
+  {
+    if(h&&h->Typ()==MATRIX_CMD)
+    {
+      matrix M=(matrix)h->Data();
+      h=h->next;
+      if(h&&h->Typ()==INT_CMD)
+      {
+        int i=(int)h->Data();
+        h=h->next;
+        if(h&&h->Typ()==INT_CMD)
+        {
+          int j=(int)h->Data();
+          res->rtyp=MATRIX_CMD;
+          res->data=(void *)evSwap(mpCopy(M),i,j);
+          return FALSE;
+        }
+      }
+    }
+    WerrorS("<matrix>,<int>,<int> expected");
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+
+matrix evRowElim(matrix M,int i,int j,int k)
+{
+  if(MATELEM(M,i,k)==NULL||MATELEM(M,j,k)==NULL)
+    return(M);
+
+  poly p=pNSet(nDiv(pGetCoeff(MATELEM(M,i,k)),pGetCoeff(MATELEM(M,j,k))));
+  pNormalize(p);
+
+  for(int l=1;l<=MATCOLS(M);l++)
+  {
+    MATELEM(M,i,l)=pSub(MATELEM(M,i,l),ppMult_qq(p,MATELEM(M,j,l)));
+    pNormalize(MATELEM(M,i,l));
+  }
+  for(int l=1;l<=MATROWS(M);l++)
+  {
+    MATELEM(M,l,j)=pAdd(MATELEM(M,l,j),ppMult_qq(p,MATELEM(M,l,i)));
+    pNormalize(MATELEM(M,l,j));
+  }
+
+  pDelete(&p);
+
+  return(M);
+}
+
+
+BOOLEAN evRowElim(leftv res,leftv h)
+{
+  if(currRingHdl)
+  {
+    if(h&&h->Typ()==MATRIX_CMD)
+    {
+      matrix M=(matrix)h->Data();
+      h=h->next;
+      if(h&&h->Typ()==INT_CMD)
+      {
+        int i=(int)h->Data();
+        h=h->next;
+        if(h&&h->Typ()==INT_CMD)
+        {
+          int j=(int)h->Data();
+          h=h->next;
+          if(h&&h->Typ()==INT_CMD)
+          {
+            int k=(int)h->Data();
+            res->rtyp=MATRIX_CMD;
+            res->data=(void *)evRowElim(mpCopy(M),i,j,k);
+            return FALSE;
+	  }
+        }
+      }
+    }
+    WerrorS("<matrix>,<int>,<int>,<int> expected");
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+
+matrix evColElim(matrix M,int i,int j,int k)
+{
+  if(MATELEM(M,k,i)==0||MATELEM(M,k,j)==0)
+    return(M);
+
+  poly p=pNSet(nDiv(pGetCoeff(MATELEM(M,k,i)),pGetCoeff(MATELEM(M,k,j))));
+  pNormalize(p);
+
+  for(int l=1;l<=MATROWS(M);l++)
+  {
+    MATELEM(M,l,i)=pSub(MATELEM(M,l,i),ppMult_qq(p,MATELEM(M,l,j)));
+    pNormalize(MATELEM(M,l,i));
+  }
+  for(int l=1;l<=MATCOLS(M);l++)
+  {
+    MATELEM(M,j,l)=pAdd(MATELEM(M,j,l),ppMult_qq(p,MATELEM(M,i,l)));
+    pNormalize(MATELEM(M,j,l));
+  }
+
+  pDelete(&p);
+
+  return(M);
+}
+
+
+BOOLEAN evColElim(leftv res,leftv h)
+{
+  if(currRingHdl)
+  {
+    if(h&&h->Typ()==MATRIX_CMD)
+    {
+      matrix M=(matrix)h->Data();
+      h=h->next;
+      if(h&&h->Typ()==INT_CMD)
+      {
+        int i=(int)h->Data();
+        h=h->next;
+        if(h&&h->Typ()==INT_CMD)
+        {
+          int j=(int)h->Data();
+          h=h->next;
+          if(h&&h->Typ()==INT_CMD)
+          {
+            int k=(int)h->Data();
+            res->rtyp=MATRIX_CMD;
+            res->data=(void *)evColElim(mpCopy(M),i,j,k);
+            return FALSE;
+	  }
+        }
+      }
+    }
+    WerrorS("<matrix>,<int>,<int>,<int> expected");
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+
+matrix evHessenberg(matrix M)
+{
+  int n=MATROWS(M);
+  if(n!=MATCOLS(M))
+    return(M);
+
+  for(int k=1,j=2;k<n-1;k++,j=k+1)
+  {
+    while(j<=n&&MATELEM(M,j,k)==0)
+      j++;
+
+    if(j<=n)
+    {
+      M=evSwap(M,j,k+1);
+
+      for(int i=j+1;i<=n;i++)
+        M=evRowElim(M,i,k+1,k);
+    }
+  }
+
+  return(M);
+}
+
+
+BOOLEAN evHessenberg(leftv res,leftv h)
+{
+  if(currRingHdl)
+  {
+    if(h&&h->Typ()==MATRIX_CMD)
+    {
+      matrix M=(matrix)h->Data();
+      res->rtyp=MATRIX_CMD;
+      res->data=(void *)evHessenberg(mpCopy(M));
+      return FALSE;
+    }
+    WerrorS("<matrix> expected");
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+
+lists evEigenvals(matrix M)
+{
+  lists l=(lists)omAllocBin(slists_bin);
+  if(MATROWS(M)!=MATCOLS(M))
+  {
+    l->Init(0);
+    return(l);
+  }
+
+  M=evHessenberg((matrix)idJet((ideal)M,0));
+
+  int n=MATROWS(M);
+  ideal e=idInit(n,1);
+  intvec *m=new intvec(n);
+
+  poly t=pOne();
+  pSetExp(t,1,1);
+  pSetm(t);
+
+  for(int j0=1,j=2,k=0;j<=n+1;j0=j,j++)
+  {
+    while(j<=n&&MATELEM(M,j,j-1)!=NULL)
+      j++;
+    if(j==j0+1)
+    {
+      e->m[k]=pHead(MATELEM(M,j0,j0));
+      (*m)[k]=1;
+      k++;
+    }
+    else
+    {
+      int n0=j-j0;
+      matrix M0=mpNew(n0,n0);
+
+      j0--;
+      for(int i=1;i<=n0;i++)
+        for(int j=1;j<=n0;j++)
+          MATELEM(M0,i,j)=pCopy(MATELEM(M,j0+i,j0+j));
+      for(int i=1;i<=n0;i++)
+        MATELEM(M0,i,i)=pSub(MATELEM(M0,i,i),pCopy(t));
+
+      intvec *m0;
+      ideal e0=singclap_factorize(mpDetBareiss(M0),&m0,2);
+
+      for(int i=0;i<IDELEMS(e0);i++)
+      {
+        if(pNext(e0->m[i])==NULL)
+	{
+          (*m)[k]=(*m0)[i];
+          k++;
+        }
+        else
+        if(pGetExp(e0->m[i],1)<2&&pGetExp(pNext(e0->m[i]),1)<2&&
+           pNext(pNext(e0->m[i]))==NULL)
+	{
+          number e1=nNeg(nCopy(pGetCoeff(e0->m[i])));
+          if(pGetExp(pNext(e0->m[i]),1)==0)
+            e->m[k]=pNSet(nDiv(pGetCoeff(pNext(e0->m[i])),e1));
+          else
+	    e->m[k]=pNSet(nDiv(e1,pGetCoeff(pNext(e0->m[i]))));
+          nDelete(&e1);
+          pNormalize(e->m[k]);
+          (*m)[k]=(*m0)[i];
+          k++;
+        }
+        else
+	{
+          e->m[k]=e0->m[i];
+          pNormalize(e->m[k]);
+          e0->m[i]=NULL;
+          (*m)[k]=(*m0)[i];
+          k++;
+	}
+      }
+
+      delete(m0);
+      idDelete(&e0);
+    }
+  }
+
+  pDelete(&t);
+  idDelete((ideal *)&M);
+
+  for(int i0=0;i0<n-1;i0++)
+  {
+    for(int i1=i0+1;i1<n;i1++)
+    {
+      if(pEqualPolys(e->m[i0],e->m[i1]))
+      {
+        (*m)[i0]+=(*m)[i1];
+        (*m)[i1]=0;
+      }
+      else
+      {
+        if(e->m[i0]==NULL&&!nGreaterZero(pGetCoeff(e->m[i1]))||
+           e->m[i1]==NULL&&
+	  (nGreaterZero(pGetCoeff(e->m[i0]))||pNext(e->m[i0])!=NULL)||
+           e->m[i0]!=NULL&&e->m[i1]!=NULL&&
+          (pNext(e->m[i0])!=NULL&&pNext(e->m[i1])==NULL||
+           pNext(e->m[i0])==NULL&&pNext(e->m[i1])==NULL&&
+           nGreater(pGetCoeff(e->m[i0]),pGetCoeff(e->m[i1]))))
+        {
+          poly e1=e->m[i0];
+          e->m[i0]=e->m[i1];
+          e->m[i1]=e1;
+          int m1=(*m)[i0];
+          (*m)[i0]=(*m)[i1];
+          (*m)[i1]=m1;
+        }
+      }
+    }
+  }
+
+  int n0=0;
+  for(int i=0;i<n;i++)
+    if((*m)[i]>0)
+      n0++;
+
+  ideal e0=idInit(n0,1);
+  intvec *m0=new intvec(n0);
+
+  for(int i=0,i0=0;i<n;i++)
+    if((*m)[i]>0)
+    {
+      e0->m[i0]=e->m[i];
+      e->m[i]=NULL;
+      (*m0)[i0]=(*m)[i];
+      i0++;
+    }
+
+  idDelete(&e);
+  delete(m);
+
+  l->Init(2);
+  l->m[0].rtyp=IDEAL_CMD;
+  l->m[0].data=e0;
+  l->m[1].rtyp=INTVEC_CMD;
+  l->m[1].data=m0;
+
+  return(l);
+}
+
+
+BOOLEAN evEigenvals(leftv res,leftv h)
+{
+  if(currRingHdl)
+  {
+    if(h&&h->Typ()==MATRIX_CMD)
+    {
+      matrix M=(matrix)h->Data();
+      res->rtyp=LIST_CMD;
+      res->data=(void *)evEigenvals(mpCopy(M));
+      return FALSE;
+    }
+    WerrorS("<matrix> expected");
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+#endif /* HAVE_EIGENVAL */
Index: kernel/eigenval.h
===================================================================
--- kernel/eigenval.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/eigenval.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,25 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: eigenval.h,v 1.1.1.1 2003-10-06 12:15:51 Singular Exp $ */
+/*
+* ABSTRACT: eigenvalues of constant square matrices
+*/
+
+#ifndef EIGENVAL_H
+#define EIGENVAL_H
+#ifdef HAVE_EIGENVAL
+
+matrix evSwap(matrix M,int i,int j);
+BOOLEAN evSwap(leftv res,leftv h);
+matrix evRowElim(matrix M,int i,int j,int k);
+BOOLEAN evRowElim(leftv res,leftv h);
+matrix evColElim(matrix M,int i,int j,int k);
+BOOLEAN evColElim(leftv res,leftv h);
+matrix evHessenberg(matrix M);
+BOOLEAN evHessenberg(leftv res,leftv h);
+lists evEigenvals(matrix M);
+BOOLEAN evEigenvals(leftv res,leftv h);
+
+#endif /* ifdef HAVE_EIGENVAL */
+#endif /* EIGENVAL_H */
Index: kernel/emacs.cc
===================================================================
--- kernel/emacs.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/emacs.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,328 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: emacs.cc,v 1.1.1.1 2003-10-06 12:15:51 Singular Exp $ */
+/*
+* ABSTRACT: Esingular main file
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#ifdef DecAlpha_OSF1
+#define _BSD
+#endif
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#ifdef ix86_Win
+#include <windows.h>
+#endif
+#include "mod2.h"
+#include "version.h"
+#include <omalloc.h>
+
+#if !defined(TSINGULAR) && !defined(ESINGULAR)
+#define ESINGULAR
+#endif
+
+#ifdef system
+#undef system
+#endif
+
+#ifndef BOOLEAN
+#define BOOLEAN int
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+#  define  DIR_SEP '/'
+#  define  DIR_SEPP "/"
+#  define  UP_DIR ".."
+
+#ifndef ix86_Win
+void error(const char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+  vfprintf(stderr, fmt, ap);
+}
+#else
+void error(char* fmt, ...)
+{
+   char buf[4096];
+   int j =0;
+   va_list args;
+   va_start(args, fmt);
+   j =   sprintf(buf,    "");
+   j += vsprintf(buf + j,fmt,args);
+   j +=  sprintf(buf + j,"\n");
+   va_end(args);
+   MessageBox(NULL, buf, "ESingular.exe", MB_ICONSTOP);
+   exit(1);
+}
+#endif
+
+#define Warn  error
+#define WarnS error
+#define StringAppend printf
+#define Print error
+
+#define feReportBug(s) fePrintReportBug(s, __FILE__, __LINE__)
+void fePrintReportBug(char* msg, char* file, int line)
+{
+  error("YOU HAVE FOUND A BUG IN SINGULAR.\n"
+"Please, email the following output to singular@mathematik.uni-kl.de\n"
+"Bug occured at %s:%d\n"
+"Message: %s\n"
+"Version: " S_UNAME S_VERSION1 " (%lu) " __DATE__ __TIME__,
+        file, line, msg, feVersionId);
+
+}
+
+#include "feResource.cc"
+#include "feOpt.cc"
+
+void mainUsage()
+{
+  error( "Use `%s --help' for a complete list of options\n", feArgv0);
+}
+
+int main(int argc, char** argv)
+{
+  char* singular = NULL;
+  char* emacs = NULL;
+  char* emacs_dir = NULL;
+  char* emacs_load = NULL;
+  int no_emacs_call = 0;
+  char cwd[MAXPATHLEN];
+
+  // parse-cmdline options
+
+  feInitResources(argv[0]);
+  feResource('S');
+  feResource('b');
+  feResource('r');
+
+  int optc, option_index;
+
+  while ((optc = fe_getopt_long(argc, argv, SHORT_OPTS_STRING,
+                                feOptSpec, &option_index))
+        != EOF)
+  {
+    switch(optc)
+    {
+        case 'h':
+          feOptHelp(feArgv0);
+          exit(0);
+
+        case '?':
+        case ':':
+        case '\0':
+          mainUsage();
+          exit(1);
+
+        case  LONG_OPTION_RETURN:
+        {
+          switch(option_index)
+          {
+#ifdef TSINGULAR
+              case FE_OPT_XTERM:
+                emacs = fe_optarg;
+              break;
+#else
+              case FE_OPT_EMACS:
+                emacs = fe_optarg;
+                break;
+
+              case FE_OPT_EMACS_DIR:
+                emacs_dir = fe_optarg;
+                break;
+
+              case FE_OPT_EMACS_LOAD:
+                emacs_load = fe_optarg;
+                break;
+#endif
+              case FE_OPT_SINGULAR:
+                singular = fe_optarg;
+                break;
+
+              case FE_OPT_NO_CALL:
+                no_emacs_call = 1;
+                break;
+
+              default:
+                goto NEXT;
+          }
+          // delete options from option-list
+          if (fe_optind > 2 && *argv[fe_optind-1] != '-' &&
+              fe_optarg != NULL && feOptSpec[option_index].has_arg)
+          {
+            argv[fe_optind-2] = NULL;
+          }
+          argv[fe_optind-1] = NULL;
+        }
+    }
+    NEXT:{}
+  }
+
+  int i, length = 0;
+  char* syscall;
+  for (i=1; i<argc; i++)
+  {
+    if (argv[i] != NULL) length += strlen(argv[i]) + 3;
+  }
+
+#ifdef TSINGULAR
+  if (emacs == NULL) emacs = feResource('X', 0);
+  if (emacs == NULL)
+  {
+    error( "Error: Can't find emacs xterm program. \n Expected it at %s or %s\n Specify alternative with --xterm=PROGRAM option,\n or set ESINGULAR_EMACS environment variable to the name of the program to use as xterm.\n",
+           feResourceDefault('X'));
+    mainUsage();
+    exit(1);
+  }
+
+  if (singular == NULL) singular = feResource("SingularXterm", 0);
+  if (singular == NULL)
+  {
+    error( "Error: Can't find singular executable.\n Expected it at %s\n Specify with --singular option,\n or set TSINGULAR_SINGULAR environment variable.\n",
+            feResourceDefault("SingularXterm"));
+    mainUsage();
+    exit(1);
+  }
+
+#ifdef ix86_Win
+#define EXTRA_XTERM_ARGS "+vb -sl 2000 -fb Courier-bold-12 -tn xterm -cr Red3"
+#else
+#define EXTRA_XTERM_ARGS ""
+#endif
+
+  syscall = (char*) omAlloc(strlen(emacs) +
+                                 strlen(singular) +
+                                 length + 300);
+  sprintf(syscall, "%s %s -e %s ", emacs, EXTRA_XTERM_ARGS, singular);
+
+  for (i=1; i<argc; i++)
+  {
+    if (argv[i] != NULL)
+    {
+      strcat(syscall, " ");
+      strcat(syscall, argv[i]);
+    }
+  }
+#else
+  // make sure  emacs, singular, emacs_dir, emacs_load are set
+  if (emacs == NULL) emacs = feResource("xemacs", 0);
+  if (emacs == NULL) emacs = feResource("emacs", 0);
+  if (emacs == NULL)
+  {
+    error( "Error: Can't find emacs or xemacs executable. \n Expected it at %s or %s\n Specify alternative with --emacs option,\n or set ESINGULAR_EMACS environment variable.\n",
+            feResourceDefault("emacs"), feResourceDefault("xemacs"));
+    mainUsage();
+    exit(1);
+  }
+
+  if (singular == NULL) singular = feResource("SingularEmacs", 0);
+  if (singular == NULL)
+  {
+    error( "Error: Can't find singular executable.\n Expected it at %s\n Specify with --singular option,\n or set ESINGULAR_SINGULAR environment variable.\n",
+            feResourceDefault("SingularEmacs"));
+    mainUsage();
+    exit(1);
+  }
+
+  if (emacs_dir == NULL) emacs_dir = feResource("EmacsDir", 0);
+  if (emacs_dir == NULL)
+  {
+    error( "Error: Can't find emacs directory for Singular lisp files. \n Expected it at %s\n Specify with --emacs_dir option,\n or set ESINGULAR_EMACS_DIR environment variable.\n",
+            feResourceDefault("EmacsDir"));
+    mainUsage();
+    exit(1);
+  }
+
+  if (emacs_load == NULL)
+  {
+    // look into env variable
+    emacs_load = getenv("ESINGULAR_EMACS_LOAD");
+    if (access(emacs_load, R_OK))
+    {
+      // look in home-dir
+      emacs_load = getenv("HOME");
+#ifdef ix86_Win
+      if ((emacs_load==NULL)||(!access(emacs_load,X_OK)))
+        emacs_load = getenv("SINGHOME");
+#endif
+      sprintf(cwd, "%s/.emacs-singular", emacs_load);
+      if (! access(cwd, R_OK))
+      {
+        emacs_load = omStrDup(cwd);
+      }
+      else
+      {
+        // try with resources
+        emacs_load = feResource("EmacsLoad", 0);
+        if (emacs_load == NULL)
+        {
+          error( "Error: Can't find emacs load file for Singular mode. \n Expected it at %s\n Specify with --emacs_load option,\n or set ESINGULAR_EMACS_LOAD environment variable,\n or put file '.emacs-singular' in your home directory.\n",
+                  feResourceDefault("EmacsLoad"));
+          mainUsage();
+          exit(1);
+        }
+      }
+    }
+  }
+
+  syscall = (char*) omAlloc(strlen(emacs) +
+                           strlen(singular) +
+                           strlen(emacs_dir) +
+                           strlen(emacs_load) +
+                           length + 300);
+  char* prefix = "--";
+  if (strstr(emacs, "xemacs") || strstr(emacs, "Xemacs") || strstr(emacs, "XEMACS"))
+    prefix = "-";
+  getcwd(cwd, MAXPATHLEN);
+  // append / at the end of cwd
+  if (cwd[strlen(cwd)-1] != '/') strcat(cwd, "/");
+
+  // Note: option -no-init-file should be equivalent to -q. Anyhow,
+  // xemacs-20.4 sometimes crashed on startup when using -q. DonŽt know why.
+  sprintf(syscall, "%s %sno-init-file %seval '(progn (setq singular-emacs-home-directory \"%s\") (load-file \"%s\") (singular-other \"%s\" \"%s\" (list ",
+          emacs, prefix, prefix, emacs_dir, emacs_load, 
+          singular, cwd);
+
+
+  for (i=1; i<argc; i++)
+  {
+    if (argv[i] != NULL)
+    {
+      strcat(syscall, "\"");
+      strcat(syscall, argv[i]);
+      strcat(syscall, "\" ");
+    }
+  }
+  strcat(syscall, ") \"singular\"))'");
+#endif
+
+  if (no_emacs_call)
+  {
+    printf("%s\n", syscall);
+  }
+  else
+  {
+    if (system(syscall) != 0)
+    {
+      error( "Error: Execution of\n%s\n", syscall);
+      mainUsage();
+      exit(1);
+    }
+  }
+}
+
+
Index: kernel/extra.cc
===================================================================
--- kernel/extra.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/extra.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1713 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/* $Id: extra.cc,v 1.1.1.1 2003-10-06 12:15:51 Singular Exp $ */
+/*
+* ABSTRACT: general interface to internals of Singular ("system" command)
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <signal.h>
+#include "mod2.h"
+
+#ifndef __MWERKS__
+#ifdef TIME_WITH_SYS_TIME
+# include <time.h>
+# ifdef HAVE_SYS_TIME_H
+#   include <sys/time.h>
+# endif
+#else
+# ifdef HAVE_SYS_TIME_H
+#   include <sys/time.h>
+# else
+#   include <time.h>
+# endif
+#endif
+#ifdef HAVE_SYS_TIMES_H
+#include <sys/times.h>
+#endif
+
+#endif
+#include <unistd.h>
+
+#include "tok.h"
+#include "ipid.h"
+#include "polys.h"
+#include "lists.h"
+#include "kutil.h"
+#include "cntrlc.h"
+#include "stairc.h"
+#include "ipshell.h"
+#include "algmap.h"
+#include "modulop.h"
+#include "febase.h"
+#include "matpol.h"
+#include "longalg.h"
+#include "ideals.h"
+#include "kstd1.h"
+#include "syz.h"
+#include "sdb.h"
+#include "feOpt.h"
+#include "distrib.h"
+#include "prCopy.h"
+#include "mpr_complex.h"
+
+#include "walk.h"
+#include "weight.h"
+
+#ifdef HAVE_SPECTRUM
+#include "spectrum.h"
+#endif
+
+#ifdef HAVE_PLURAL
+#include "ring.h"
+#include "gring.h"
+#include "ipconv.h"
+#endif
+
+#ifdef ix86_Win /* only for the DLLTest */
+/* #include "WinDllTest.h" */
+#ifdef HAVE_DL
+#include "mod_raw.h"
+#endif
+#endif
+
+// for tests of t-rep-GB
+#include "tgb.cc"
+
+// Define to enable many more system commands
+#ifndef MAKE_DISTRIBUTION
+#define HAVE_EXTENDED_SYSTEM 1
+#endif
+
+#ifdef HAVE_FACTORY
+#define SI_DONT_HAVE_GLOBAL_VARS
+#include "clapsing.h"
+#include "clapconv.h"
+#include "kstdfac.h"
+#endif
+
+#include "silink.h"
+#include "walk.h"
+
+#include "fast_maps.h"
+
+#ifdef HAVE_EIGENVAL
+#include "eigenval.h"
+#endif
+
+#ifdef HAVE_GMS
+#include "gms.h"
+#endif
+
+/*
+ *   New function/system-calls that will be included as dynamic module
+ * should be inserted here.
+ * - without HAVE_DYNAMIC_LOADING: these functions comes as system("....");
+ * - with    HAVE_DYNAMIC_LOADING: these functions are loaded as module.
+ */
+#ifndef HAVE_DYNAMIC_LOADING
+
+#ifdef HAVE_PCV
+#include "pcv.h"
+#endif
+
+#endif /* not HAVE_DYNAMIC_LOADING */
+
+// see clapsing.cc for a description of the `FACTORY_*' options
+
+#ifdef FACTORY_GCD_STAT
+#include "gcd_stat.h"
+#endif
+
+#ifdef FACTORY_GCD_TIMING
+#define TIMING
+#include "timing.h"
+TIMING_DEFINE_PRINTPROTO( contentTimer );
+TIMING_DEFINE_PRINTPROTO( algContentTimer );
+TIMING_DEFINE_PRINTPROTO( algLcmTimer );
+#endif
+
+void piShowProcList();
+#ifndef MAKE_DISTRIBUTION
+static BOOLEAN jjEXTENDED_SYSTEM(leftv res, leftv h);
+#endif
+
+
+//void emStart();
+/*2
+*  the "system" command
+*/
+BOOLEAN jjSYSTEM(leftv res, leftv args)
+{
+  if(args->Typ() == STRING_CMD)
+  {
+    const char *sys_cmd=(char *)(args->Data());
+    leftv h=args->next;
+// ONLY documented system calls go here
+// Undocumented system calls go down into #ifdef HAVE_EXTENDED_SYSTEM
+/*==================== nblocks ==================================*/
+    if (strcmp(sys_cmd, "nblocks") == 0)
+    {
+      ring r;
+      if (h == NULL)
+      {
+        if (currRingHdl != NULL)
+        {
+          r = IDRING(currRingHdl);
+        }
+        else
+        {
+          WerrorS("no ring active");
+          return TRUE;
+        }
+      }
+      else
+      {
+        if (h->Typ() != RING_CMD)
+        {
+          WerrorS("ring expected");
+          return TRUE;
+        }
+        r = (ring) h->Data();
+      }
+      res->rtyp = INT_CMD;
+      res->data = (void*) (rBlocks(r) - 1);
+      return FALSE;
+    }
+/*==================== version ==================================*/
+    if(strcmp(sys_cmd,"version")==0)
+    {
+      res->rtyp=INT_CMD;
+      res->data=(void *)SINGULAR_VERSION;
+      return FALSE;
+    }
+    else
+/*==================== gen ==================================*/
+    if(strcmp(sys_cmd,"gen")==0)
+    {
+      res->rtyp=INT_CMD;
+      res->data=(void *)npGen;
+      return FALSE;
+    }
+    else
+/*==================== sh ==================================*/
+    if(strcmp(sys_cmd,"sh")==0)
+    {
+      res->rtyp=INT_CMD;
+      #ifndef __MWERKS__
+      if (h==NULL) res->data = (void *)system("sh");
+      else if (h->Typ()==STRING_CMD)
+        res->data = (void*) system((char*)(h->Data()));
+      else
+        WerrorS("string expected");
+      #else
+      res->data=(void *)0;
+      #endif
+      return FALSE;
+    }
+    else
+/*==================== uname ==================================*/
+    if(strcmp(sys_cmd,"uname")==0)
+    {
+      res->rtyp=STRING_CMD;
+      res->data = omStrDup(S_UNAME);
+      return FALSE;
+    }
+    else
+/*==================== with ==================================*/
+    if(strcmp(sys_cmd,"with")==0)
+    {
+      if (h==NULL)
+      {
+        res->rtyp=STRING_CMD;
+        res->data=(void *)omStrDup(versionString());
+        return FALSE;
+      }
+      else if (h->Typ()==STRING_CMD)
+      {
+        #define TEST_FOR(A) if(strcmp(s,A)==0) res->data=(void *)1; else
+        char *s=(char *)h->Data();
+        res->rtyp=INT_CMD;
+        #ifdef HAVE_DBM
+          TEST_FOR("DBM")
+        #endif
+        #ifdef HAVE_DLD
+          TEST_FOR("DLD")
+        #endif
+        #ifdef HAVE_FACTORY
+          TEST_FOR("factory")
+        #endif
+        #ifdef HAVE_LIBFAC_P
+          TEST_FOR("libfac")
+        #endif
+        #ifdef HAVE_MPSR
+          TEST_FOR("MP")
+        #endif
+        #ifdef HAVE_READLINE
+          TEST_FOR("readline")
+        #endif
+        #ifdef HAVE_TCL
+          TEST_FOR("tcl")
+        #endif
+        #ifdef TEST_MAC_ORDER
+          TEST_FOR("MAC_ORDER");
+        #endif
+        #ifdef HAVE_NS
+          TEST_FOR("Namespaces");
+        #endif
+        #ifdef HAVE_DYNAMIC_LOADING
+          TEST_FOR("DynamicLoading");
+        #endif
+        #ifdef HAVE_EIGENVAL
+          TEST_FOR("eigenval");
+        #endif
+        #ifdef HAVE_GMS
+          TEST_FOR("gms");
+        #endif
+          ;
+        return FALSE;
+        #undef TEST_FOR
+      }
+      return TRUE;
+    }
+    else
+/*==================== browsers ==================================*/
+    if (strcmp(sys_cmd,"browsers")==0)
+    {
+      res->rtyp = STRING_CMD;
+      char* b = StringSetS("");
+      feStringAppendBrowsers(0);
+      res->data = omStrDup(b);
+      return FALSE;
+    }
+    else
+/*==================== pid ==================================*/
+    if (strcmp(sys_cmd,"pid")==0)
+    {
+      res->rtyp=INT_CMD;
+    #ifndef MSDOS
+    #ifndef __MWERKS__
+      res->data=(void *)getpid();
+    #else
+      res->data=(void *)1;
+    #endif
+    #else
+      res->data=(void *)1;
+    #endif
+      return FALSE;
+    }
+    else
+/*==================== getenv ==================================*/
+    if (strcmp(sys_cmd,"getenv")==0)
+    {
+      if ((h!=NULL) && (h->Typ()==STRING_CMD))
+      {
+        res->rtyp=STRING_CMD;
+        char *r=getenv((char *)h->Data());
+        if (r==NULL) r="";
+        res->data=(void *)omStrDup(r);
+        return FALSE;
+      }
+      else
+      {
+        WerrorS("string expected");
+        return TRUE;
+      }
+    }
+    else
+/*==================== setenv ==================================*/
+    if (strcmp(sys_cmd,"setenv")==0)
+    {
+#ifdef HAVE_SETENV
+      if (h!=NULL && h->Typ()==STRING_CMD && h->Data() != NULL &&
+          h->next != NULL && h->next->Typ() == STRING_CMD
+          && h->next->Data() != NULL)
+      {
+        res->rtyp=STRING_CMD;
+        setenv((char *)h->Data(), (char *)h->next->Data(), 1);
+        res->data=(void *)omStrDup((char *)h->next->Data());
+        feReInitResources();
+        return FALSE;
+      }
+      else
+      {
+        WerrorS("two strings expected");
+        return TRUE;
+      }
+#else
+      WerrorS("setenv not supported on this platform");
+      return TRUE;
+#endif
+    }
+    else
+/*==================== Singular ==================================*/
+    if (strcmp(sys_cmd, "Singular") == 0)
+    {
+      res->rtyp=STRING_CMD;
+      char *r=feResource("Singular");
+      if (r != NULL)
+        res->data = (void*) omStrDup( r );
+      else
+        res->data = (void*) omStrDup("");
+      return FALSE;
+    }
+    else
+/*==================== options ==================================*/
+    if (strstr(sys_cmd, "--") == sys_cmd)
+    {
+      if (strcmp(sys_cmd, "--") == 0)
+      {
+        fePrintOptValues();
+        return FALSE;
+      }
+
+      feOptIndex opt = feGetOptIndex(&sys_cmd[2]);
+      if (opt == FE_OPT_UNDEF)
+      {
+        Werror("Unknown option %s", sys_cmd);
+        Werror("Use 'system(\"--\");' for listing of available options");
+        return TRUE;
+      }
+
+      // for Untyped Options (help version),
+      // setting it just triggers action
+      if (feOptSpec[opt].type == feOptUntyped)
+      {
+        feSetOptValue(opt,0);
+        return FALSE;
+      }
+
+      if (h == NULL)
+      {
+        if (feOptSpec[opt].type == feOptString)
+        {
+          res->rtyp = STRING_CMD;
+          if (feOptSpec[opt].value != NULL)
+            res->data = omStrDup((char*) feOptSpec[opt].value);
+          else
+            res->data = omStrDup("");
+        }
+        else
+        {
+          res->rtyp = INT_CMD;
+          res->data = feOptSpec[opt].value;
+        }
+        return FALSE;
+      }
+
+      if (h->Typ() != STRING_CMD &&
+          h->Typ() != INT_CMD)
+      {
+        Werror("Need string or int argument to set option value");
+        return TRUE;
+      }
+      char* errormsg;
+      if (h->Typ() == INT_CMD)
+      {
+        if (feOptSpec[opt].type == feOptString)
+        {
+          Werror("Need string argument to set value of option %s", sys_cmd);
+          return TRUE;
+        }
+        errormsg = feSetOptValue(opt, (int) h->Data());
+        if (errormsg != NULL)
+          Werror("Option '--%s=%d' %s", sys_cmd, (int) h->Data(), errormsg);
+      }
+      else
+      {
+        errormsg = feSetOptValue(opt, (char*) h->Data());
+        if (errormsg != NULL)
+          Werror("Option '--%s=%s' %s", sys_cmd, (char*) h->Data(), errormsg);
+      }
+      if (errormsg != NULL) return TRUE;
+      return FALSE;
+    }
+    else
+/*==================== HC ==================================*/
+    if (strcmp(sys_cmd,"HC")==0)
+    {
+      res->rtyp=INT_CMD;
+      res->data=(void *)HCord;
+      return FALSE;
+    }
+    else
+/*==================== random ==================================*/
+    if(strcmp(sys_cmd,"random")==0)
+    {
+      if ((h!=NULL) &&(h->Typ()==INT_CMD))
+      {
+        siRandomStart=(int)h->Data();
+#ifdef buildin_rand
+        siSeed=siRandomStart;
+#else
+        srand((unsigned int)siRandomStart);
+#endif
+#ifdef HAVE_FACTORY
+        factoryseed(siRandomStart);
+#endif
+        return FALSE;
+      }
+      else if (h != NULL)
+      {
+        WerrorS("int expected");
+        return TRUE;
+      }
+      res->rtyp=INT_CMD;
+      res->data=(void*) siRandomStart;
+      return FALSE;
+    }
+/*==================== complexNearZero ======================*/
+    if(strcmp(sys_cmd,"complexNearZero")==0)
+    {
+      if (h->Typ()==NUMBER_CMD )
+      {
+        if ( h->next!=NULL && h->next->Typ()==INT_CMD )
+        {
+          if ( !rField_is_long_C() )
+            {
+              Werror( "unsupported ground field!");
+              return TRUE;
+            }
+          else
+            {
+              res->rtyp=INT_CMD;
+              res->data=(void*)complexNearZero((gmp_complex*)h->Data(),(int)h->next->Data());
+              return FALSE;
+            }
+        }
+        else
+        {
+          Werror( "expected <int> as third parameter!");
+          return TRUE;
+        }
+      }
+      else
+      {
+        Werror( "expected <number> as second parameter!");
+        return TRUE;
+      }
+    }
+/*==================== getPrecDigits ======================*/
+    if(strcmp(sys_cmd,"getPrecDigits")==0)
+    {
+      if ( !rField_is_long_C() && !rField_is_long_R() )
+      {
+        Werror( "unsupported ground field!");
+        return TRUE;
+      }
+      res->rtyp=INT_CMD;
+      res->data=(void*)getGMPFloatDigits();
+      return FALSE;
+    }
+/*==================== neworder =============================*/
+// should go below
+#ifdef HAVE_LIBFAC_P
+    if(strcmp(sys_cmd,"neworder")==0)
+    {
+      if ((h!=NULL) &&(h->Typ()==IDEAL_CMD))
+      {
+        res->rtyp=STRING_CMD;
+        res->data=(void *)singclap_neworder((ideal)h->Data());
+        return FALSE;
+      }
+      else
+        WerrorS("ideal expected");
+    }
+    else
+#endif
+#ifndef HAVE_DYNAMIC_LOADING
+/*==================== pcv ==================================*/
+#ifdef HAVE_PCV
+    if(strcmp(sys_cmd,"pcvLAddL")==0)
+    {
+      return pcvLAddL(res,h);
+    }
+    else
+    if(strcmp(sys_cmd,"pcvPMulL")==0)
+    {
+      return pcvPMulL(res,h);
+    }
+    else
+    if(strcmp(sys_cmd,"pcvMinDeg")==0)
+    {
+      return pcvMinDeg(res,h);
+    }
+    else
+    if(strcmp(sys_cmd,"pcvP2CV")==0)
+    {
+      return pcvP2CV(res,h);
+    }
+    else
+    if(strcmp(sys_cmd,"pcvCV2P")==0)
+    {
+      return pcvCV2P(res,h);
+    }
+    else
+    if(strcmp(sys_cmd,"pcvDim")==0)
+    {
+      return pcvDim(res,h);
+    }
+    else
+    if(strcmp(sys_cmd,"pcvBasis")==0)
+    {
+      return pcvBasis(res,h);
+    }
+    else
+#endif
+/*==================== eigenvalues ==================================*/
+#ifdef HAVE_EIGENVAL
+    if(strcmp(sys_cmd,"hessenberg")==0)
+    {
+      return evHessenberg(res,h);
+    }
+    else
+    if(strcmp(sys_cmd,"eigenvals")==0)
+    {
+      return evEigenvals(res,h);
+    }
+    else
+#endif
+/*==================== Gauss-Manin system ==================================*/
+#ifdef HAVE_GMS
+    if(strcmp(sys_cmd,"gmsnf")==0)
+    {
+      return gmsNF(res,h);
+    }
+    else
+#endif
+#endif /* HAVE_DYNAMIC_LOADING */
+/*==================== contributors =============================*/
+   if(strcmp(sys_cmd,"contributors") == 0)
+   {
+     res->rtyp=STRING_CMD;
+     res->data=(void *)omStrDup(
+       "Olaf Bachmann, Hubert Grassmann, Kai Krueger, Wolfgang Neumann, Thomas Nuessler, Wilfred Pohl, Jens Schmidt, Mathias Schulze, Thomas Siebert, Ruediger Stobbe, Moritz Wenk, Tim Wichmann");
+     return FALSE;
+   }
+   else
+/*==================== spectrum =============================*/
+   #ifdef HAVE_SPECTRUM
+   if(strcmp(sys_cmd,"spectrum") == 0)
+   {
+     if (h->Typ()!=POLY_CMD)
+     {
+       WerrorS("poly expected");
+       return TRUE;
+     }
+     if (h->next==NULL)
+       return spectrumProc(res,h);
+     if (h->next->Typ()!=INT_CMD)
+     {
+       WerrorS("poly,int expected");
+       return TRUE;
+     }
+     if(((int)h->next->Data())==1)
+       return spectrumfProc(res,h);
+     return spectrumProc(res,h);
+   }
+   else
+/*==================== semic =============================*/
+   if(strcmp(sys_cmd,"semic") == 0)
+   {
+     if ((h->next!=NULL)
+     && (h->Typ()==LIST_CMD)
+     && (h->next->Typ()==LIST_CMD))
+     {
+       if (h->next->next==NULL)
+         return semicProc(res,h,h->next);
+       else if (h->next->next->Typ()==INT_CMD)
+         return semicProc3(res,h,h->next,h->next->next);
+     }
+     return TRUE;
+   }
+   else
+/*==================== spadd =============================*/
+   if(strcmp(sys_cmd,"spadd") == 0)
+   {
+     if ((h->next!=NULL)
+     && (h->Typ()==LIST_CMD)
+     && (h->next->Typ()==LIST_CMD))
+     {
+       if (h->next->next==NULL)
+         return spaddProc(res,h,h->next);
+     }
+     return TRUE;
+   }
+   else
+/*==================== spmul =============================*/
+   if(strcmp(sys_cmd,"spmul") == 0)
+   {
+     if ((h->next!=NULL)
+     && (h->Typ()==LIST_CMD)
+     && (h->next->Typ()==INT_CMD))
+     {
+       if (h->next->next==NULL)
+         return spmulProc(res,h,h->next);
+     }
+     return TRUE;
+   }
+   else
+   #endif
+#ifdef HAVE_PLURAL
+/*==================== PrintMat  =================*/
+      if (strcmp(sys_cmd, "PrintMat") == 0)
+      {
+        int a;
+        int b;
+        ring r;
+        int metric;
+        if ((h!=NULL) && (h->Typ()==INT_CMD))
+        {
+          a=(int)h->CopyD();
+          h=h->next;
+        }
+        else return TRUE;
+        if ((h!=NULL) && (h->Typ()==INT_CMD))
+        {
+          b=(int)h->CopyD();
+          h=h->next;
+        }
+        else return TRUE;
+        if ((h!=NULL) && (h->Typ()==RING_CMD))
+        {
+          r=(ring)h->Data();
+          h=h->next;
+        }
+        else return TRUE;
+        if ((h!=NULL) && (h->Typ()==INT_CMD))
+        {
+          metric=(int)h->CopyD();
+        }
+        res->rtyp=MATRIX_CMD;
+        if (rIsPluralRing(r)) res->data=nc_PrintMat(a,b,r,metric);
+        else res->data=NULL;
+        return FALSE;
+      }
+/*==================== twostd  =================*/
+      if (strcmp(sys_cmd, "twostd") == 0)
+      {
+        ideal I;
+        if ((h!=NULL) && (h->Typ()==IDEAL_CMD))
+        {
+          I=(ideal)h->CopyD();
+          res->rtyp=IDEAL_CMD;
+          if (rIsPluralRing(currRing)) res->data=twostd(I);
+          else res->data=I;
+          setFlag(res,FLAG_TWOSTD);
+          setFlag(res,FLAG_STD);
+        }
+        else return TRUE;
+        return FALSE;
+      }
+/*==================== lie bracket =================*/
+    if (strcmp(sys_cmd, "bracket") == 0)
+    {
+      poly p;
+      poly q;
+      if ((h!=NULL) && (h->Typ()==POLY_CMD))
+      {
+        p=(poly)h->CopyD();
+        h=h->next;
+      }
+      else return TRUE;
+      if ((h!=NULL) && (h->Typ()==POLY_CMD))
+      {
+        q=(poly)h->Data();
+      }
+      else return TRUE;
+      res->rtyp=POLY_CMD;
+      if (rIsPluralRing(currRing))  res->data=nc_p_Bracket_qq(p,q);
+      else res->data=NULL;
+      return FALSE;
+    }
+/*==================== PLURAL =================*/
+    if (strcmp(sys_cmd, "PLURAL") == 0)
+    {
+      matrix C;
+      matrix D;
+      number nN;
+      poly pN;
+      int i,j;
+      sleftv tmp_v;
+      memset(&tmp_v,0,sizeof(tmp_v));
+
+      if (currRing->nc==NULL)
+      {
+        currRing->nc=(nc_struct *)omAlloc0(sizeof(nc_struct));
+        currRing->nc->ref=1;
+        currRing->nc->basering=currRing;
+      }
+      else
+      {
+        WarnS("redefining algebra structure");
+        if (currRing->nc->ref>1) // in use by somebody else
+          currRing->nc->ref--;
+        else
+          ncKill(currRing); /* kill the previous nc data */
+        currRing->nc=(nc_struct *)omAlloc0(sizeof(nc_struct));
+        currRing->nc->ref=1;
+        currRing->nc->basering=currRing;
+      }
+      currRing->nc->type=nc_general;
+      /* C is either a poly (coeff - an int or a number) or a  matrix */
+      if (h==NULL) return TRUE;
+      leftv hh=h->next;
+      h->next=NULL;
+      switch(h->Typ())
+      {
+        case MATRIX_CMD: { C=(matrix)h->CopyD(); break; }
+
+        case INT_CMD: case NUMBER_CMD:
+        {
+          i=iiTestConvert(h->Typ(), POLY_CMD);
+          if (i==0)
+          {
+            Werror("cannot convert to poly");
+            return TRUE;
+          }
+          iiConvert(h->Typ(), POLY_CMD, i, h, &tmp_v);
+          pN=(poly)tmp_v.Data();
+          break;
+        }
+
+        case POLY_CMD:  {pN=(poly)h->Data(); break;}
+
+        default: return TRUE;
+      }
+      if (h->Typ()==MATRIX_CMD)
+      {
+	currRing->nc->type=nc_undef; /* to analyze later ! */
+	//	currRing->nc->IsSkewConstant=NULL;
+      }
+      else
+      {
+	nN=pGetCoeff(pN); // pN is not NULL anyway
+	if (nIsZero(nN)) 
+	{
+	  Werror("zero coefficients are not allowed");
+	  return TRUE;
+	}
+	if (nIsOne(nN)) currRing->nc->type=nc_lie; 
+	else currRing->nc->type=nc_skew;
+	currRing->nc->IsSkewConstant=1;
+	/* create matrix C */
+	C=mpNew(currRing->N,currRing->N);
+	for(i=1;i<currRing->N;i++)
+	{
+	  for(j=i+1;j<=currRing->N;j++)
+	  {
+	    MATELEM(C,i,j) = nc_p_CopyPut(pN,currRing);
+	    //  MATELEM(C,i,j)=pCopy(pN);
+	  }
+	}
+      }
+      pN=NULL;
+      h=hh;
+      /* D is either a poly or a matrix */
+      if (h==NULL) { pN=NULL;}  /* D is zero matrix */
+      else
+      {
+        switch(h->Typ())
+        {
+          case MATRIX_CMD: { D=(matrix)h->CopyD(); break;}
+
+          case INT_CMD: case NUMBER_CMD:
+          {
+            i=iiTestConvert(h->Typ(), POLY_CMD);
+            if (i==0)
+            {
+              Werror("cannot convert to poly");
+              return TRUE;
+            }
+            iiConvert(h->Typ(), POLY_CMD, i, h, &tmp_v);
+            pN=(poly)tmp_v.Data();
+            break;
+          }
+
+          case POLY_CMD:  { pN=(poly)h->Data();break;}
+
+          default: return TRUE;
+        }
+      } /* end else h==NULL */
+      if (pN==NULL)
+      {
+	if (currRing->nc->type==nc_lie) 
+	{
+	  currRing->nc->type=nc_skew; /* even commutative! */
+	}
+      }
+      else  
+      { 
+	if (currRing->nc->type==nc_skew) currRing->nc->type=nc_general; 
+      } /* end pN==NULL */
+      if (h==NULL)
+      {
+         WerrorS("expected `system(\"PLURAL\",<matrix>,<matrix>)`");
+         idDelete((ideal *)&(currRing->nc->C));
+         omFreeSize((ADDRESS)currRing->nc,sizeof(nc_struct));
+         currRing->nc=NULL;
+         return TRUE;
+      }
+      if (h->Typ()!=MATRIX_CMD)
+      {
+        D=mpNew(currRing->N,currRing->N);
+        /* create matrix D */
+        for(i=1;i<currRing->N;i++)
+        {
+          for(j=i+1;j<=currRing->N;j++)
+          {
+            MATELEM(D,i,j) = nc_p_CopyPut(pN,currRing);
+            //            MATELEM(D,i,j)=pCopy(pN);
+          }
+        }
+      }
+      else currRing->nc->type=nc_undef;
+      tmp_v.CleanUp();
+      pN=NULL;
+      /* Now we proceed with C and D */
+      matrix COM;
+      currRing->nc->MT=(matrix *)omAlloc0(currRing->N*(currRing->N-1)/2*sizeof(matrix));
+      currRing->nc->MTsize=(int *)omAlloc0(currRing->N*(currRing->N-1)/2*sizeof(int));
+      currRing->nc->C=C;
+      currRing->nc->D=D;
+      COM=mpCopy(currRing->nc->C);
+      poly p;
+      short DefMTsize=7;
+      int tmpIsSkewConstant=1;
+      int IsNonComm=0;
+      pN=nc_p_CopyGet(MATELEM(currRing->nc->C,1,2),currRing);
+      //      pN=MATELEM(currRing->nc->C,1,2);
+
+      for(i=1;i<currRing->N;i++)
+      {
+        for(j=i+1;j<=currRing->N;j++)
+        {
+          if (MATELEM(currRing->nc->C,i,j)==NULL)
+          {
+            Werror("Incorrect input : matrix of coefficients contains zeros in the upper triangle!");
+            return TRUE;
+          }
+          if (!nEqual(pGetCoeff(pN),pGetCoeff(MATELEM(currRing->nc->C,i,j)))) tmpIsSkewConstant=0;
+          if (MATELEM(currRing->nc->D,i,j)==NULL) /* quasicommutative case */
+          {
+            currRing->nc->MTsize[UPMATELEM(i,j,currRing->N)]=1;
+            /* 1x1 mult.matrix */
+            currRing->nc->MT[UPMATELEM(i,j,currRing->N)]=mpNew(1,1);
+          }
+          else /* pure noncommutative case*/
+          {
+            IsNonComm=1;
+            MATELEM(COM,i,j)=NULL;
+            currRing->nc->MTsize[UPMATELEM(i,j,currRing->N)]=DefMTsize; /* default sizes */
+            currRing->nc->MT[UPMATELEM(i,j,currRing->N)]=mpNew(DefMTsize,DefMTsize);
+          }
+          p=pOne();
+          pSetCoeff(p,nCopy(pGetCoeff(MATELEM(currRing->nc->C,i,j))));
+          pSetExp(p,i,1);
+          pSetExp(p,j,1);
+          pSetm(p);
+          //          p=pAdd(p,pCopy(MATELEM(currRing->nc->D,i,j)));
+          p=pAdd(p,nc_p_CopyGet(MATELEM(currRing->nc->D,i,j),currRing));
+          //          MATELEM(currRing->nc->MT[UPMATELEM(i,j,currRing->N)],1,1)=p;
+          MATELEM(currRing->nc->MT[UPMATELEM(i,j,currRing->N)],1,1)=nc_p_CopyPut(p,currRing);
+          pDelete(&p);
+          p=NULL;
+        }
+        /* set MT[i,j,1,1] to c_i_j*x_i*x_j + D_i_j */
+      }
+      if (currRing->nc->type==nc_undef)
+      {
+        if (IsNonComm==1)
+        {
+          assume(pN!=NULL);
+	  if ((tmpIsSkewConstant==1) && (nIsOne(pGetCoeff(pN)))) currRing->nc->type=nc_lie;
+	  else currRing->nc->type=nc_general;
+	}
+	if (IsNonComm==0) 
+	{
+	  currRing->nc->type=nc_skew; /* could be also commutative */
+	  currRing->nc->IsSkewConstant=tmpIsSkewConstant;
+	}
+      }
+      currRing->nc->COM=COM;
+      return FALSE;
+    }
+    else
+#endif
+/*================= Extended system call ========================*/
+   {
+     #ifndef MAKE_DISTRIBUTION
+     return(jjEXTENDED_SYSTEM(res, args));
+     #else
+     Werror( "system(\"%s\",...) %s", sys_cmd, feNotImplemented );
+     #endif
+   }
+  } /* typ==string */
+  return TRUE;
+}
+
+
+#ifdef HAVE_EXTENDED_SYSTEM
+// You can put your own system calls here
+#include "fglmcomb.cc"
+#include "fglm.h"
+#ifdef HAVE_NEWTON
+#include <hc_newton.h>
+#endif
+#include "mpsr.h"
+#include "mod_raw.h"
+
+static BOOLEAN jjEXTENDED_SYSTEM(leftv res, leftv h)
+{
+  if(h->Typ() == STRING_CMD)
+  {
+    char *sys_cmd=(char *)(h->Data());
+    h=h->next;
+/*==================== locNF ======================================*/
+    if(strcmp(sys_cmd,"locNF")==0)
+    {
+      if (h != NULL && h->Typ() == VECTOR_CMD)
+      {
+        poly f=(poly)h->Data();
+        h=h->next;
+        if (h != NULL && h->Typ() == MODUL_CMD)
+        {
+          ideal m=(ideal)h->Data();
+          assumeStdFlag(h);
+          h=h->next;
+          if (h != NULL && h->Typ() == INT_CMD)
+          {
+            int n=(int)h->Data();
+            h=h->next;
+            if (h != NULL && h->Typ() == INTVEC_CMD)
+            {
+              intvec *v=(intvec *)h->Data();
+
+              /* == now the work starts == */
+
+              short * iv=iv2array(v);
+              poly r=0;
+              poly hp=ppJetW(f,n,iv);
+              int s=MATCOLS(m);
+              int j=0;
+              matrix T=mpInitI(s,1,0);
+
+              while (hp != NULL)
+              {
+                if (pDivisibleBy(m->m[j],hp))
+                  {
+                    if (MATELEM(T,j+1,1)==0)
+                    {
+                      MATELEM(T,j+1,1)=pDivideM(pHead(hp),pHead(m->m[j]));
+                    }
+                    else
+                    {
+                      pAdd(MATELEM(T,j+1,1),pDivideM(pHead(hp),pHead(m->m[j])));
+                    }
+                    hp=ppJetW(ksOldSpolyRed(m->m[j],hp,0),n,iv);
+                    j=0;
+                  }
+                else
+                {
+                  if (j==s-1)
+                  {
+                    r=pAdd(r,pHead(hp));
+                    hp=pLmDeleteAndNext(hp); /* hp=pSub(hp,pHead(hp));*/
+                    j=0;
+                  }
+                  else
+                  {
+                    j++;
+                  }
+                }
+              }
+
+              matrix Temp=mpTransp((matrix) idVec2Ideal(r));
+              matrix R=mpNew(MATCOLS((matrix) idVec2Ideal(f)),1);
+              for (int k=1;k<=MATROWS(Temp);k++)
+              {
+                MATELEM(R,k,1)=MATELEM(Temp,k,1);
+              }
+
+              lists L=(lists)omAllocBin(slists_bin);
+              L->Init(2);
+              L->m[0].rtyp=MATRIX_CMD;   L->m[0].data=(void *)R;
+              L->m[1].rtyp=MATRIX_CMD;   L->m[1].data=(void *)T;
+              res->data=L;
+              res->rtyp=LIST_CMD;
+              // iv aufraeumen
+              omFree(iv);
+            }
+            else
+            {
+              Warn ("4th argument: must be an intvec!");
+            }
+          }
+          else
+          {
+            Warn("3rd argument must be an int!!");
+          }
+        }
+        else
+        {
+          Warn("2nd argument must be a module!");
+        }
+      }
+      else
+      {
+        Warn("1st argument must be a vector!");
+      }
+      return FALSE;
+    }
+    else
+/*==================== interred ==================================*/
+    #if 0
+    if(strcmp(sys_cmd,"interred")==0)
+    {
+      res->data=(char *)kIR((ideal)h->Data(),currQuotient);
+      res->rtyp=h->Typ();
+      return ((h->Typ()!=IDEAL_CMD) && (h->Typ()!=MODUL_CMD));
+    }
+    else
+    #endif
+#ifdef RDEBUG
+/*==================== poly debug ==================================*/
+    if(strcmp(sys_cmd,"p")==0)
+    {
+      pDebugPrint((poly)h->Data());
+      return FALSE;
+    }
+    else
+/*==================== ring debug ==================================*/
+    if(strcmp(sys_cmd,"r")==0)
+    {
+      rDebugPrint((ring)h->Data());
+      return FALSE;
+    }
+    else
+#endif
+/*==================== mtrack ==================================*/
+    if(strcmp(sys_cmd,"mtrack")==0)
+    {
+#ifdef OM_TRACK
+      om_Opts.MarkAsStatic = 1;
+      FILE *fd = NULL;
+      int max = 5;
+      while (h != NULL)
+      {
+        omMarkAsStaticAddr(h);
+        if (fd == NULL && h->Typ()==STRING_CMD)
+        {
+          fd = fopen((char*) h->Data(), "w");
+          if (fd == NULL)
+            Warn("Can not open %s for writing og mtrack. Using stdout");
+        }
+        if (h->Typ() == INT_CMD)
+        {
+          max = (int) h->Data();
+        }
+        h = h->Next();
+      }
+      omPrintUsedTrackAddrs((fd == NULL ? stdout : fd), max);
+      if (fd != NULL) fclose(fd);
+      om_Opts.MarkAsStatic = 0;
+      return FALSE;
+#else
+     WerrorS("mtrack not supported without OM_TRACK");
+     return TRUE;
+#endif
+    }
+/*==================== mtrack_all ==================================*/
+    if(strcmp(sys_cmd,"mtrack_all")==0)
+    {
+#ifdef OM_TRACK
+      om_Opts.MarkAsStatic = 1;
+      FILE *fd = NULL;
+      if ((h!=NULL) &&(h->Typ()==STRING_CMD))
+      {
+        fd = fopen((char*) h->Data(), "w");
+        if (fd == NULL)
+          Warn("Can not open %s for writing og mtrack. Using stdout");
+        omMarkAsStaticAddr(h);
+      }
+      // OB: TBC print to fd
+      omPrintUsedAddrs((fd == NULL ? stdout : fd), 5);
+      if (fd != NULL) fclose(fd);
+      om_Opts.MarkAsStatic = 0;
+      return FALSE;
+#else
+     WerrorS("mtrack not supported without OM_TRACK");
+     return TRUE;
+#endif
+    }
+    else
+/*==================== backtrace ==================================*/
+    if(strcmp(sys_cmd,"backtrace")==0)
+    {
+#ifndef OM_NDEBUG
+      omPrintCurrentBackTrace(stdout);
+      return FALSE;
+#else
+     WerrorS("btrack not supported without OM_TRACK");
+     return TRUE;
+#endif
+    }
+    else
+/*==================== naIdeal ==================================*/
+    if(strcmp(sys_cmd,"naIdeal")==0)
+    {
+      if ((h!=NULL) &&(h->Typ()==IDEAL_CMD))
+      {
+        naSetIdeal((ideal)h->Data());
+        return FALSE;
+      }
+      else
+         WerrorS("ideal expected");
+    }
+    else
+/*==================== isSqrFree =============================*/
+#ifdef HAVE_FACTORY
+    if(strcmp(sys_cmd,"isSqrFree")==0)
+    {
+      if ((h!=NULL) &&(h->Typ()==POLY_CMD))
+      {
+        res->rtyp=INT_CMD;
+        res->data=(void *)singclap_isSqrFree((poly)h->Data());
+        return FALSE;
+      }
+      else
+        WerrorS("poly expected");
+    }
+    else
+#endif
+/*==================== pDivStat =============================*/
+#if defined(PDEBUG) || defined(PDIV_DEBUG)
+    if(strcmp(sys_cmd,"pDivStat")==0)
+    {
+      extern void pPrintDivisbleByStat();
+      pPrintDivisbleByStat();
+      return FALSE;
+    }
+    else
+#endif
+/*==================== alarm ==================================*/
+#ifndef __MWERKS__
+#ifndef MSDOS
+#ifndef atarist
+#ifdef unix
+    if(strcmp(sys_cmd,"alarm")==0)
+    {
+      if ((h!=NULL) &&(h->Typ()==INT_CMD))
+      {
+        // standard variant -> SIGALARM (standard: abort)
+        //alarm((unsigned)h->next->Data());
+        // process time (user +system): SIGVTALARM
+        struct itimerval t,o;
+        memset(&t,0,sizeof(t));
+        t.it_value.tv_sec     =(unsigned)h->Data();
+        setitimer(ITIMER_VIRTUAL,&t,&o);
+        return FALSE;
+      }
+      else
+        WerrorS("int expected");
+    }
+    else
+#endif
+#endif
+#endif
+#endif
+/*==================== red =============================*/
+#if 0
+    if(strcmp(sys_cmd,"red")==0)
+    {
+      if ((h!=NULL) &&(h->Typ()==IDEAL_CMD))
+      {
+        res->rtyp=IDEAL_CMD;
+        res->data=(void *)kStdred((ideal)h->Data(),NULL,testHomog,NULL);
+        setFlag(res,FLAG_STD);
+        return FALSE;
+      }
+      else
+        WerrorS("ideal expected");
+    }
+    else
+#endif
+/*==================== algfetch =====================*/
+    if (strcmp(sys_cmd,"algfetch")==0)
+    {
+      int k;
+      idhdl w;
+      ideal i0, i1;
+      ring r0=(ring)h->Data();
+      leftv v = h->next;
+      w = r0->idroot->get(v->Name(),myynest);
+      if (w!=NULL)
+      {
+        if (IDTYP(w)==IDEAL_CMD)
+        {
+          i0 = IDIDEAL(w);
+          i1 = idInit(IDELEMS(i0),i0->rank);
+          for (k=0; k<IDELEMS(i1); k++)
+          {
+            i1->m[k] = maAlgpolyFetch(r0, i0->m[k]);
+          }
+          res->rtyp = IDEAL_CMD;
+          res->data = (void*)i1;
+          return FALSE;
+        }
+        else if (IDTYP(w)==POLY_CMD)
+        {
+          res->rtyp = POLY_CMD;
+          res->data = (void*)maAlgpolyFetch(r0,IDPOLY(w));
+          return FALSE;
+        }
+        else
+          WerrorS("`system(\"algfetch\",<ideal>/<poly>)` expected");
+      }
+      else
+        Werror("`%s` not found in `%s`",v->Name(),h->Name());
+    }
+    else
+/*==================== algmap =======================*/
+    if (strcmp(sys_cmd,"algmap")==0)
+    {
+      int k;
+      idhdl w;
+      ideal i0, i1, i, j;
+      ring r0=(ring)h->Data();
+      leftv v = h->next;
+      w = r0->idroot->get(v->Name(),myynest);
+      i0 = IDIDEAL(w);
+      v = v->next;
+      i = (ideal)v->Data();
+      v = v->next;
+      j = (ideal)v->Data();
+      i1 = idInit(IDELEMS(i0),i0->rank);
+      for (k=0; k<IDELEMS(i1); k++)
+      {
+        i1->m[k] = maAlgpolyMap(r0, i0->m[k], i, j);
+      }
+      res->rtyp = IDEAL_CMD;
+      res->data = (void*)i1;
+      return FALSE;
+    }
+    else
+#ifdef HAVE_FACTORY
+/*==================== fastcomb =============================*/
+    if(strcmp(sys_cmd,"fastcomb")==0)
+    {
+      if ((h!=NULL) &&(h->Typ()==IDEAL_CMD))
+      {
+        int i=0;
+        if (h->next!=NULL)
+        {
+          if (h->next->Typ()!=POLY_CMD)
+          {
+            Warn("Wrong types for poly= comb(ideal,poly)");
+          }
+        }
+        res->rtyp=POLY_CMD;
+        res->data=(void *) fglmLinearCombination(
+                           (ideal)h->Data(),(poly)h->next->Data());
+        return FALSE;
+      }
+      else
+        WerrorS("ideal expected");
+    }
+    else
+/*==================== comb =============================*/
+    if(strcmp(sys_cmd,"comb")==0)
+    {
+      if ((h!=NULL) &&(h->Typ()==IDEAL_CMD))
+      {
+        int i=0;
+        if (h->next!=NULL)
+        {
+          if (h->next->Typ()!=POLY_CMD)
+          {
+              Warn("Wrong types for poly= comb(ideal,poly)");
+          }
+        }
+        res->rtyp=POLY_CMD;
+        res->data=(void *)fglmNewLinearCombination(
+                            (ideal)h->Data(),(poly)h->next->Data());
+        return FALSE;
+      }
+      else
+        WerrorS("ideal expected");
+    }
+    else
+#endif
+#ifdef FACTORY_GCD_TEST
+/*=======================gcd Testerei ================================*/
+    if ( ! strcmp( sys_cmd, "setgcd" ) ) {
+        if ( (h != NULL) && (h->Typ() == INT_CMD) ) {
+            CFPrimitiveGcdUtil::setAlgorithm( (int)h->Data() );
+            return FALSE;
+        } else
+            WerrorS("int expected");
+    }
+    else
+#endif
+
+#ifdef FACTORY_GCD_TIMING
+    if ( ! strcmp( sys_cmd, "gcdtime" ) ) {
+        TIMING_PRINT( contentTimer, "time used for content: " );
+        TIMING_PRINT( algContentTimer, "time used for algContent: " );
+        TIMING_PRINT( algLcmTimer, "time used for algLcm: " );
+        TIMING_RESET( contentTimer );
+        TIMING_RESET( algContentTimer );
+        TIMING_RESET( algLcmTimer );
+        return FALSE;
+    }
+    else
+#endif
+
+#ifdef FACTORY_GCD_STAT
+    if ( ! strcmp( sys_cmd, "gcdstat" ) ) {
+        printGcdTotal();
+        printContTotal();
+        resetGcdTotal();
+        resetContTotal();
+        return FALSE;
+    }
+    else
+#endif
+#if !defined(HAVE_NS)
+/*==================== lib ==================================*/
+    if(strcmp(sys_cmd,"LIB")==0)
+    {
+      idhdl hh=idroot->get((char*)h->Data(),0);
+      if ((hh!=NULL)&&(IDTYP(hh)==PROC_CMD))
+      {
+        res->rtyp=STRING_CMD;
+        char *r=iiGetLibName(IDPROC(hh));
+        if (r==NULL) r="";
+        res->data=omStrDup(r);
+        return FALSE;
+      }
+      else
+        Warn("`%s` not found",(char*)h->Data());
+    }
+    else
+#endif
+/*==================== listall ===================================*/
+    if(strcmp(sys_cmd,"listall")==0)
+    {
+      int showproc=1;
+      if ((h!=NULL) && (h->Typ()==INT_CMD)) showproc=(int)h->Data();
+#ifdef HAVE_NS
+      listall(showproc);
+#else
+      idhdl hh=IDROOT;
+      while (hh!=NULL)
+      {
+        if (IDDATA(hh)==(void *)currRing) PrintS("(R)");
+        else PrintS("   ");
+        Print("::%s, typ %s level %d\n",
+               IDID(hh),Tok2Cmdname(IDTYP(hh)),IDLEV(hh));
+        hh=IDNEXT(hh);
+      }
+      hh=IDROOT;
+      while (hh!=NULL)
+      {
+        if ((IDTYP(hh)==RING_CMD)
+        || (IDTYP(hh)==QRING_CMD)
+        || (IDTYP(hh)==PACKAGE_CMD))
+        {
+          idhdl h2=IDRING(hh)->idroot;
+          while (h2!=NULL)
+          {
+            if (IDDATA(h2)==(void *)currRing) PrintS("(R)");
+            else PrintS("   ");
+            Print("%s::%s, typ %s level %d\n",
+            IDID(hh),IDID(h2),Tok2Cmdname(IDTYP(h2)),IDLEV(h2));
+            h2=IDNEXT(h2);
+          }
+        }
+        hh=IDNEXT(hh);
+      }
+#endif /* HAVE_NS */
+      return FALSE;
+    }
+    else
+/*==================== proclist =================================*/
+    if(strcmp(sys_cmd,"proclist")==0)
+    {
+      piShowProcList();
+      return FALSE;
+    }
+    else
+/* ==================== newton ================================*/
+#ifdef HAVE_NEWTON
+    if(strcmp(sys_cmd,"newton")==0)
+    {
+      if ((h->Typ()!=POLY_CMD)
+      || (h->next->Typ()!=INT_CMD)
+      || (h->next->next->Typ()!=INT_CMD))
+      {
+        WerrorS("system(\"newton\",<poly>,<int>,<int>) expected");
+        return TRUE;
+      }
+      poly  p=(poly)(h->Data());
+      int l=pLength(p);
+      short *points=(short *)omAlloc(currRing->N*l*sizeof(short));
+      int i,j,k;
+      k=0;
+      poly pp=p;
+      for (i=0;pp!=NULL;i++)
+      {
+        for(j=1;j<=currRing->N;j++)
+        {
+          points[k]=pGetExp(pp,j);
+          k++;
+        }
+        pIter(pp);
+      }
+      hc_ERG r=hc_KOENIG(currRing->N,      // dimension
+                l,      // number of points
+                (short*) points,   // points: x_1, y_1,z_1, x_2,y_2,z2,...
+                currRing->OrdSgn==-1,
+                (int) (h->next->Data()),      // 1: Milnor, 0: Newton
+                (int) (h->next->next->Data()) // debug
+               );
+      //----<>---Output-----------------------
+
+
+//  PrintS("Bin jetzt in extra.cc bei der Auswertung.\n"); // **********
+
+
+      lists L=(lists)omAllocBin(slists_bin);
+      L->Init(6);
+      L->m[0].rtyp=STRING_CMD;               // newtonnumber;
+      L->m[0].data=(void *)omStrDup(r.nZahl);
+      L->m[1].rtyp=INT_CMD;
+      L->m[1].data=(void *)r.achse;          // flag for unoccupied axes
+      L->m[2].rtyp=INT_CMD;
+      L->m[2].data=(void *)r.deg;            // #degenerations
+      if ( r.deg != 0)              // only if degenerations exist
+      {
+        L->m[3].rtyp=INT_CMD;
+        L->m[3].data=(void *)r.anz_punkte;     // #points
+        //---<>--number of points------
+        int anz = r.anz_punkte;    // number of points
+        int dim = (currRing->N);     // dimension
+        intvec* v = new intvec( anz*dim );
+        for (i=0; i<anz*dim; i++)    // copy points
+          (*v)[i] = r.pu[i];
+        L->m[4].rtyp=INTVEC_CMD;
+        L->m[4].data=(void *)v;
+        //---<>--degenerations---------
+        int deg = r.deg;    // number of points
+        intvec* w = new intvec( r.speicher );  // necessary memeory
+        i=0;               // start copying
+        do
+        {
+          (*w)[i] = r.deg_tab[i];
+          i++;
+        }
+        while (r.deg_tab[i-1] != -2);   // mark for end of list
+        L->m[5].rtyp=INTVEC_CMD;
+        L->m[5].data=(void *)w;
+      }
+      else
+      {
+        L->m[3].rtyp=INT_CMD; L->m[3].data=(char *)0;
+        L->m[4].rtyp=DEF_CMD;
+        L->m[5].rtyp=DEF_CMD;
+      }
+
+      res->data=(void *)L;
+      res->rtyp=LIST_CMD;
+      // free all pointer in r:
+      delete[] r.nZahl;
+      delete[] r.pu;
+      delete[] r.deg_tab;      // Ist das ein Problem??
+
+      omFreeSize((ADDRESS)points,currRing->N*l*sizeof(short));
+      return FALSE;
+    }
+    else
+#endif
+/*==================== sdb_flags =================*/
+#ifdef HAVE_SDB
+    if (strcmp(sys_cmd, "sdb_flags") == 0)
+    {
+      if ((h!=NULL) && (h->Typ()==INT_CMD))
+      {
+        sdb_flags=(int)h->Data();
+      }
+      else
+      {
+        WerrorS("system(\"sdb_flags\",`int`) expected");
+        return TRUE;
+      }
+      return FALSE;
+    }
+    else
+/*==================== sdb_edit =================*/
+    if (strcmp(sys_cmd, "sdb_edit") == 0)
+    {
+      if ((h!=NULL) && (h->Typ()==PROC_CMD))
+      {
+        procinfov p=(procinfov)h->Data();
+        sdb_edit(p);
+      }
+      else
+      {
+        WerrorS("system(\"sdb_edit\",`proc`) expected");
+        return TRUE;
+      }
+      return FALSE;
+    }
+    else
+#endif
+/*==================== GF =================*/
+#if 0
+    if (strcmp(sys_cmd, "GF") == 0)
+    {
+      int c=rChar(currRing);
+      setCharacteristic( c, 2);
+      CanonicalForm F( convSingGFClapGF( (poly)h->Data() ) );
+      res->rtyp=POLY_CMD;
+      res->data=convClapGFSingGF( F );
+      return FALSE;
+    }
+    else
+#endif
+/*==================== stdX =================*/
+    if (strcmp(sys_cmd, "std") == 0)
+    {
+      ideal i1;
+      int i2;
+      if ((h!=NULL) && (h->Typ()==MODUL_CMD))
+      {
+        i1=(ideal)h->CopyD();
+        h=h->next;
+      }
+      else return TRUE;
+      if ((h!=NULL) && (h->Typ()==INT_CMD))
+      {
+        i2=(int)h->Data();
+      }
+      else return TRUE;
+      res->rtyp=MODUL_CMD;
+      res->data=idXXX(i1,i2);
+      return FALSE;
+    }
+    else
+#ifdef HAVE_WALK
+/*==================== walk stuff =================*/
+    if (strcmp(sys_cmd, "walkNextWeight") == 0)
+    {
+      if (h == NULL || h->Typ() != INTVEC_CMD ||
+          h->next == NULL || h->next->Typ() != INTVEC_CMD ||
+          h->next->next == NULL || h->next->next->Typ() != IDEAL_CMD)
+      {
+        Werror("system(\"walkNextWeight\", intvec, intvec, ideal) expected");
+        return TRUE;
+      }
+
+      if (((intvec*) h->Data())->length() != currRing->N ||
+          ((intvec*) h->next->Data())->length() != currRing->N)
+      {
+        Werror("system(\"walkNextWeight\" ...) intvecs not of length %d\n",
+               currRing->N);
+        return TRUE;
+      }
+      res->data = (void*) walkNextWeight(((intvec*) h->Data()),
+                                         ((intvec*) h->next->Data()),
+                                         (ideal) h->next->next->Data());
+      if (res->data == (void*) 0 || res->data == (void*) 1)
+      {
+        res->rtyp = INT_CMD;
+      }
+      else
+      {
+        res->rtyp = INTVEC_CMD;
+      }
+      return FALSE;
+    }
+    else if (strcmp(sys_cmd, "walkInitials") == 0)
+    {
+      if (h == NULL || h->Typ() != IDEAL_CMD)
+      {
+        WerrorS("system(\"walkInitials\", ideal) expected");
+        return TRUE;
+      }
+
+      res->data = (void*) walkInitials((ideal) h->Data());
+      res->rtyp = IDEAL_CMD;
+      return FALSE;
+    }
+    else
+#endif
+#ifdef ix86_Win
+#ifdef HAVE_DL
+/*==================== DLL =================*/
+/* testing the DLL functionality under Win32 */
+      if (strcmp(sys_cmd, "DLL") == 0)
+      {
+        typedef void  (*Void_Func)();
+        typedef int  (*Int_Func)(int);
+        void *hh=dynl_open("WinDllTest.dll");
+        if ((h!=NULL) && (h->Typ()==INT_CMD))
+        {
+          int (*f)(int);
+          if (hh!=NULL)
+          {
+            int (*f)(int);
+            f=(Int_Func)dynl_sym(hh,"PlusDll");
+            int i=10;
+            if (f!=NULL) printf("%d\n",f(i));
+            else PrintS("cannot find PlusDll\n");
+          }
+        }
+        else
+        {
+          void (*f)();
+          f= (Void_Func)dynl_sym(hh,"TestDll");
+          if (f!=NULL) f();
+          else PrintS("cannot find TestDll\n");
+        }
+        return FALSE;
+      }
+      else
+#endif
+#endif
+/*==================== eigenvalues ==================================*/
+#ifdef HAVE_EIGENVAL
+    if(strcmp(sys_cmd,"eigenvals")==0)
+    {
+      return evEigenvals(res,h);
+    }
+    else
+#endif
+/*==================== Gauss-Manin system ==================================*/
+#ifdef HAVE_GMS
+    if(strcmp(sys_cmd,"gmsnf")==0)
+    {
+      return gmsNF(res,h);
+    }
+    else
+#endif
+/*==================== t-rep-GB ==================================*/
+    if (strcmp(sys_cmd, "trepgb")==0)
+    {
+      ring r = currRing;
+      ideal i = (ideal)h->Data();
+      res->data=t_rep_gb(r,i);
+      res->rtyp=IDEAL_CMD;
+      return(FALSE);
+    }
+    else
+/*==================== Error =================*/
+      Werror( "system(\"%s\",...) %s", sys_cmd, feNotImplemented );
+  }
+  return TRUE;
+}
+#endif // HAVE_EXTENDED_SYSTEM
Index: kernel/fast_maps.cc
===================================================================
--- kernel/fast_maps.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/fast_maps.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,719 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    fast_maps.cc
+ *  Purpose: implementation of fast maps
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 02/01
+ *  Version: $Id: fast_maps.cc,v 1.1.1.1 2003-10-06 12:15:51 Singular Exp $
+ *******************************************************************/
+#include "mod2.h"
+#include <omalloc.h>
+#include "p_polys.h"
+#include "prCopy.h"
+#include "ideals.h"
+#include "ring.h"
+#include "febase.h"
+#include "fast_maps.h"
+
+// define if you want to use special dest_ring
+#define HAVE_DEST_R 1
+// define if you want to use special src_ring
+#define HAVE_SRC_R 1
+// define if you want to use optimization step
+#define HAVE_MAP_OPTIMIZE 1
+
+/*******************************************************************************
+**
+*F  maMaxExp  . . . . . . . .  returns bound on maximal exponent of result of map
+*/
+// return maximal monomial if max_map_monomials are substituted into pi_m
+static poly maGetMaxExpP(poly* max_map_monomials,
+                         int n_max_map_monomials, ring map_r,
+                         poly pi_m, ring pi_r)
+{
+  int n = min(pi_r->N, n_max_map_monomials);
+  int i, j;
+  Exponent_t e_i, e_j;
+  poly m_i, map_j = p_Init(map_r);
+
+  for (i=1; i <= n; i++)
+  {
+    e_i = p_GetExp(pi_m, i, pi_r);
+    m_i = max_map_monomials[i-1];
+    if (e_i > 0 && m_i != NULL && ! p_IsConstantComp(m_i, map_r))
+    {
+      for (j = 1; j<= map_r->N; j++)
+      {
+        e_j = p_GetExp(m_i, j, map_r);
+        if (e_j > 0)
+        {
+          p_AddExp(map_j, j, e_j*e_i, map_r);
+        }
+      }
+    }
+  }
+  return map_j;
+}
+
+// returns maximal exponent if map_id is applied to pi_id
+static Exponent_t maGetMaxExp(ideal pi_id, ring pi_r, ideal map_id, ring map_r)
+{
+  Exponent_t max=0;
+  poly* max_map_monomials = (poly*) omAlloc(IDELEMS(map_id)*sizeof(poly));
+  poly max_pi_i, max_map_i;
+
+  int i, j;
+  for (i=0; i<IDELEMS(map_id); i++)
+  {
+    max_map_monomials[i] = p_GetMaxExpP(map_id->m[i], map_r);
+  }
+
+  for (i=0; i<IDELEMS(pi_id); i++)
+  {
+    max_pi_i = p_GetMaxExpP(pi_id->m[i], pi_r);
+    max_map_i = maGetMaxExpP(max_map_monomials, IDELEMS(map_id), map_r,
+                              max_pi_i, pi_r);
+    Exponent_t temp = p_GetMaxExp(max_map_i, map_r);
+    if (temp > max){
+      max=temp;
+    }
+
+    p_LmFree(max_pi_i, pi_r);
+    p_LmFree(max_map_i, map_r);
+  }
+  return max;
+}
+
+
+/*******************************************************************************
+**
+*F  debugging stuff
+*/
+#ifndef NDEBUG
+void maMonomial_Out(mapoly monomial, ring src_r, ring dest_r)
+{
+  p_wrp(monomial->src, src_r);
+  printf(" ref:%d", monomial->ref);
+  if (dest_r != NULL)
+  {
+    printf(" dest:");
+    p_wrp(monomial->dest, dest_r);
+  }
+  if (monomial->f1!=NULL) { printf(" f1:%x", (unsigned int)monomial->f1->src);
+                            // p_wrp(monomial->f1->src, src_r);
+                          }
+  if (monomial->f2!=NULL) { printf(" f2:%x",(unsigned int)monomial->f2->src);
+                            // p_wrp(monomial->f2->src, src_r);
+                          }
+  printf("\n");
+  fflush(stdout);
+}
+
+void maPoly_Out(mapoly mpoly, ring src_r, ring dest_r)
+{
+  while (mpoly != NULL)
+  {
+    maMonomial_Out(mpoly, src_r, dest_r);
+    mpoly = mpoly->next;
+  }
+}
+#endif
+
+/*******************************************************************************
+**
+*F  mapolyCreate  . . . . . . . . . . . . . . .  Creates mapoly
+*/
+static omBin mapolyBin = omGetSpecBin(sizeof(mapoly_s));
+static omBin macoeffBin = omGetSpecBin(sizeof(macoeff_s));
+
+mapoly maMonomial_Create(poly p, ring r_p, sBucket_pt bucket)
+{
+  mapoly mp = (mapoly) omAlloc0Bin(mapolyBin);
+  //p_wrp(p,r_p);printf(" (%x) created\n",mp);
+  mp->src = p;
+  p->next = NULL;
+
+  if (bucket != NULL)
+  {
+    mp->coeff = (macoeff) omAlloc0Bin(macoeffBin);
+    mp->coeff->bucket = bucket;
+    mp->coeff->n = pGetCoeff(p);
+  }
+  mp->ref = 1;
+  return mp;
+}
+
+void maMonomial_Destroy(mapoly mp, ring src_r, ring dest_r)
+{
+  if (mp != NULL)
+  {
+    p_LmFree(mp->src, src_r);
+    if (mp->coeff != NULL)
+    {
+      macoeff coeff, next = mp->coeff;
+      do
+      {
+        coeff = next;
+        next = coeff->next;
+        omFreeBin(coeff, macoeffBin);
+      }
+      while (next != NULL);
+      if (mp->dest != NULL)
+      {
+        assume(dest_r != NULL);
+        p_Delete(&(mp->dest), dest_r);
+      }
+    }
+  }
+  omFreeBin(mp, mapolyBin);
+}
+
+/*******************************************************************************
+**
+*F  maPoly_InsertMonomial . . . . . . . . .insertion of a monomial into mapoly
+*/
+mapoly maPoly_InsertMonomial(mapoly &into, mapoly what, ring src_r)
+{
+  if (into == NULL)
+  {
+    into = what;
+    return what;
+  }
+
+  mapoly iter = into;
+  mapoly prev = NULL;
+
+  Top:
+  p_LmCmpAction(iter->src, what->src, src_r, goto Equal, goto Greater, goto Smaller);
+
+  Greater:
+  if (iter->next == NULL)
+  {
+    iter->next = what;
+    return what;
+  }
+  prev = iter;
+  iter = iter->next;
+  goto Top;
+
+  Smaller:
+  if (prev == NULL)
+  {
+    into = what;
+    what->next = iter;
+    return what;
+  }
+  prev->next = what;
+  what->next = iter;
+  return what;
+
+  Equal:
+  iter->ref += what->ref;
+  macoeff coeff = what->coeff;
+  if (coeff != NULL)
+  {
+    while (coeff->next != NULL) coeff = coeff->next;
+    coeff->next = iter->coeff;
+    iter->coeff = what->coeff;
+    what->coeff = NULL;
+  }
+  maMonomial_Free(what, src_r);
+  return iter;
+}
+
+mapoly maPoly_InsertMonomial(mapoly &into, poly p, ring src_r, sBucket_pt bucket)
+{
+  return maPoly_InsertMonomial(into, maMonomial_Create(p, src_r, bucket), src_r);
+}
+
+static void maPoly_InsertPoly(mapoly &into, poly what, ring src_r, sBucket_pt bucket)
+{
+  poly next;
+
+  while (what != NULL)
+  {
+    next = what->next;
+    maPoly_InsertMonomial(into, what, src_r, bucket);
+    what = next;
+  }
+}
+
+/*******************************************************************************
+**
+*F  maMap_Create . . . . . . . . . . . . . . . . . . . . create stuff
+*/
+
+void maMap_CreatePolyIdeal(ideal map_id, ring map_r, ring src_r, ring dest_r,
+                           mapoly &mp, maideal &mideal)
+{
+  mideal = (maideal) omAlloc0(sizeof(maideal_s));
+  mideal->n = IDELEMS(map_id);
+  mideal->buckets = (sBucket_pt*) omAlloc0(mideal->n*sizeof(sBucket_pt));
+  int i;
+  mp = NULL;
+
+  for (i=0; i<mideal->n; i++)
+  {
+    if (map_id->m[i] != NULL)
+    {
+      mideal->buckets[i] = sBucketCreate(dest_r);
+      maPoly_InsertPoly(mp,
+#ifdef PDEBUG
+                        prShallowCopyR(map_id->m[i], map_r, src_r),
+#else
+                        prShallowCopyR_NoSort(map_id->m[i], map_r, src_r),
+#endif
+                        src_r,
+                        mideal->buckets[i]);
+    }
+  }
+}
+
+
+void maMap_CreateRings(ideal map_id, ring map_r,
+                       ideal image_id, ring image_r,
+                       ring &src_r, ring &dest_r, BOOLEAN &simple)
+{
+#if HAVE_SRC_R > 0
+  int* weights = (int*) omAlloc0(map_r->N*sizeof(int));
+  int i;
+  int n = min(map_r->N, IDELEMS(image_id));
+
+  for (i=0; i<n; i++)
+  {
+    weights[i] = pLength(image_id->m[i]);
+  }
+  src_r = rModifyRing_Wp(map_r, weights);
+#else
+  src_r = map_r;
+#endif
+
+#if HAVE_DEST_R > 0
+  Exponent_t maxExp = maGetMaxExp(map_id, map_r, image_id, image_r);
+  if (maxExp <=  1) maxExp = 2;
+  else if (maxExp > (Exponent_t) image_r->bitmask)
+    maxExp = (Exponent_t) image_r->bitmask;
+  dest_r = rModifyRing_Simple(image_r, TRUE, TRUE, maxExp,  simple);
+#else
+  dest_r = image_r;
+#endif
+}
+
+static void maMap_KillRings(ring map_r, ring image_r, ring src_r, ring dest_r)
+{
+  if (map_r != src_r)
+    rKillModified_Wp_Ring(src_r);
+  if (image_r != dest_r)
+    rKillModifiedRing_Simple(dest_r);
+}
+
+/*******************************************************************************
+**
+*F  misc  . . . . . . . . . . . . . . . . . . . . . . . . . . . .  misc  stuff
+*/
+
+ideal maIdeal_2_Ideal(maideal m_id, ring dest_r)
+{
+  ideal res = idInit(m_id->n, 1);
+  int l;
+
+  for (int i= 0; i < m_id->n; i++)
+  {
+    if (m_id->buckets[i]!=NULL)
+      sBucketDestroyAdd(m_id->buckets[i], &(res->m[i]), &l);
+  }
+  omFree(m_id);
+  return res;
+}
+
+void maPoly_GetLength(mapoly mp, int &length)
+{
+  length = 0;
+  while (mp != NULL)
+  {
+    length++;
+    mp = mp->next;
+  }
+}
+
+
+/*******************************************************************************
+**
+*F  fast_map  . . . . . . . . . . . . . . . . . . . . . . . . . .the real thing
+*/
+
+ideal fast_map(ideal map_id, ring map_r, ideal image_id, ring image_r)
+{
+  ring src_r, dest_r;
+  ideal dest_id, res_id;
+  int length = 0;
+  BOOLEAN no_sort;
+
+  // construct rings we work in:
+  // src_r: Wp with Weights set to length of poly in image_id
+  // dest_r: Simple ring without degree ordering and short exponents
+  maMap_CreateRings(map_id, map_r, image_id, image_r, src_r, dest_r, no_sort);
+
+  // construct dest_id
+  if (dest_r != image_r)
+    dest_id = idrShallowCopyR(image_id, image_r, dest_r);
+  else
+    dest_id = image_id;
+
+  // construct mpoly and mideal
+  mapoly mp;
+  maideal mideal;
+  maMap_CreatePolyIdeal(map_id, map_r, src_r, dest_r, mp, mideal);
+
+  if (TEST_OPT_PROT)
+  {
+    maPoly_GetLength(mp, length);
+    Print("map[%d:%d]{%d:", dest_r->bitmask, dest_r->ExpL_Size, length);
+  }
+
+  // do the optimization step
+#if HAVE_MAP_OPTIMIZE > 0
+  if (mp!=NULL) maPoly_Optimize(mp, src_r);
+#endif
+  if (TEST_OPT_PROT)
+  {
+    maPoly_GetLength(mp, length);
+    Print("%d}", length);
+  }
+
+  // do the actual evaluation
+  maPoly_Eval(mp, src_r, dest_id, dest_r, length);
+  if (TEST_OPT_PROT) Print(".");
+
+  // collect the results back into an ideal
+  ideal res_dest_id = maIdeal_2_Ideal(mideal, dest_r);
+  if (TEST_OPT_PROT) Print(".");
+
+  // convert result back to image_r
+  ideal res_image_id;
+  if (dest_r != image_r)
+  {
+    //if (no_sort) see Old/m134si.tst
+    //  res_image_id = idrShallowCopyR_NoSort(res_dest_id, dest_r, image_r);
+    //else
+      res_image_id = idrShallowCopyR(res_dest_id, dest_r, image_r);
+    id_ShallowDelete(&res_dest_id, dest_r);
+  }
+  else
+    res_image_id = res_dest_id;
+
+  if (TEST_OPT_PROT) Print(".");
+  // clean-up the rings
+  maMap_KillRings(map_r, image_r, src_r, dest_r);
+
+  if (TEST_OPT_PROT)
+    Print("\n");
+
+  return res_image_id;
+}
+
+
+/**********************************************************************
+* Evaluation stuff                                                    *
+**********************************************************************/
+
+// substitute p everywhere the monomial occours,
+// return the number of substitutions
+static int maPoly_Substitute(macoeff c, poly p, ring dest_r)
+{
+  // substitute the monomial: go through macoeff
+  int len=pLength(p);
+  int done=0;
+  while (c!=NULL)
+  {
+    done++;
+    poly t=pp_Mult_nn(p,c->n,dest_r);
+    sBucket_Add_p(c->bucket, t, len);
+    c=c->next;
+  }
+  return done;
+}
+
+static poly maPoly_EvalMon(poly src, ring src_r, poly* dest_id, ring dest_r)
+{
+  int i;
+  int e;
+  poly p=NULL;
+  poly pp;
+  for(i=1;i<=src_r->N;i++)
+  {
+    e=p_GetExp(src,i,src_r);
+    if (e>0)
+    {
+      pp=dest_id[i-1];
+      if (pp==NULL)
+      {
+        p_Delete(&p,dest_r);
+        return NULL;
+      }
+      if ((p==NULL) /* && (e>0)*/)
+      {
+        p=p_Copy(pp /*dest_id[i-1]*/,dest_r);
+        e--;
+      }
+      while (e>0)
+      {
+        p=p_Mult_q(p,p_Copy(pp /*dest_id[i-1]*/,dest_r),dest_r);
+        e--;
+      }
+    }
+  }
+  if (p==NULL) p=p_ISet(1,dest_r);
+  return p;
+}
+
+void maPoly_Eval(mapoly root, ring src_r, ideal dest_id, ring dest_r, int total_cost)
+{
+  // invert the list rooted at root:
+  if ((root!=NULL) && (root->next!=NULL))
+  {
+    mapoly q=root->next;
+    mapoly qn;
+    root->next=NULL;
+    do
+    {
+      qn=q->next;
+      q->next=root;
+      root=q;
+      q=qn;
+    }
+    while (qn !=NULL);
+  }
+
+  total_cost /= 10;
+  int next_print_cost = total_cost;
+
+  // the evaluation -----------------------------------------
+  mapoly p=root;
+  int cost = 0;
+
+  while (p!=NULL)
+  {
+    // look at each mapoly: compute its value in ->dest
+    assume (p->dest==NULL);
+    {
+      if ((p->f1!=NULL)&&(p->f2!=NULL))
+      {
+#if 0
+        printf("found prod:");
+        p_wrp(p->src,src_r);printf("=");
+        p_wrp(p->f1->src,src_r);printf(" * ");
+        p_wrp(p->f2->src,src_r);printf("\n");
+#endif
+        poly f1=p->f1->dest;
+        poly f2=p->f2->dest;
+        if (p->f1->ref>0) f1=p_Copy(f1,dest_r);
+        else
+        {
+          // we own p->f1->dest now (in f1)
+          p->f1->dest=NULL;
+        }
+        if (p->f2->ref>0) f2=p_Copy(f2,dest_r);
+        else
+        {
+          // we own p->f2->dest now (in f2)
+          p->f2->dest=NULL;
+        }
+        maMonomial_Free(p->f1,src_r, dest_r);
+        maMonomial_Free(p->f2,src_r, dest_r);
+        p->dest=p_Mult_q(f1,f2,dest_r);
+      } /* factors : 2 */
+      else
+      {
+        //printf("compute "); p_wrp(p->src,src_r);printf("\n");
+        assume((p->f1==NULL) && (p->f2==NULL));
+        //if(p->f1!=NULL) { printf(" but f1="); p_wrp(p->f1->src,src_r);printf("\n"); }
+        //if(p->f2!=NULL) { printf(" but f2="); p_wrp(p->f2->src,src_r);printf("\n"); }
+        // no factorization provided, use the classical method:
+        p->dest=maPoly_EvalMon(p->src,src_r,dest_id->m,dest_r);
+        //p_wrp(p->dest, dest_r); printf(" is p->dest\n");
+      }
+    } /* p->dest==NULL */
+    // substitute the monomial: go through macoeff
+    p->ref -= maPoly_Substitute(p->coeff, p->dest, dest_r);
+    //printf("subst done\n");
+    if (total_cost)
+    {
+      assume(TEST_OPT_PROT);
+      cost++;
+      if (cost > next_print_cost)
+      {
+        Print("-");
+        next_print_cost += total_cost;
+      }
+    }
+
+    mapoly pp=p;
+    p=p->next;
+    //p_wrp(pp->src, src_r);
+    if (pp->ref<=0)
+    {
+      //printf(" (%x) killed\n",pp);
+      maMonomial_Destroy(pp, src_r, dest_r);
+    }
+    //else
+    //  printf(" (%x) not killed, ref=%d\n",pp,pp->ref);
+  }
+}
+
+
+/*******************************************************************************
+**
+*F  maEggt  . . . . . . . . . . . . . . . . . . . . . . . .  returns extended ggt
+*/
+// return NULL if deg(ggt(m1, m2)) < 2
+// else return m = ggT(m1, m2) and q1, q2 such that m1 = q1*m m2 = q2*m
+static poly maEggT(const poly m1, const poly m2, poly &q1, poly &q2,const ring r)
+{
+
+  int i;
+  int dg = 0;
+  poly ggt = NULL;
+  q1 = p_Init(r);
+  q2 = p_Init(r);
+  ggt=p_Init(r);
+
+  for (i=1;i<=r->N;i++) {
+    Exponent_t e1 = p_GetExp(m1, i, r);
+    Exponent_t e2 = p_GetExp(m2, i, r);
+    if (e1 > 0 && e2 > 0){
+      Exponent_t em = (e1 > e2 ? e2 : e1);
+      dg += em;
+      p_SetExp(ggt, i, em, r);
+      p_SetExp(q1, i, e1 - em, r);
+      p_SetExp(q2, i, e2 - em, r);
+    }
+    else {
+      p_SetExp(q1, i, e1, r);
+      p_SetExp(q2, i, e2, r);
+    }
+  }
+  if (dg>1)
+  {
+    p_Setm(ggt, r);
+    p_Setm(q1, r);
+    p_Setm(q2, r);
+
+
+  }
+  else {
+    p_LmFree(ggt, r);
+    p_LmFree(q1, r);
+    p_LmFree(q2, r);
+    ggt = NULL;
+  }
+  return ggt;
+}
+
+/********************************************************************
+ **                                                                 *
+ * maFindBestggT                                                    *
+ * finds ggT with the highest cost                                  *
+ *******************************************************************/
+
+static mapoly maFindBestggT(mapoly mp, mapoly & choice, mapoly & fp, mapoly & fq,const ring r)
+{
+  int ggt_deg = 0;
+  poly p = mp->src;
+  mapoly iter = choice;
+  poly ggT = NULL;
+  fp = NULL;
+  fq = NULL;
+  poly fp_p=NULL;
+  poly fq_p=NULL;
+  choice=NULL;
+  while ((iter != NULL) && (pDeg(iter->src, r) > ggt_deg))
+  {
+    //    maMonomial_Out(iter, r, NULL);
+    poly q1, q2, q;
+
+    q = maEggT(p, iter->src, q1, q2,r);
+    if (q != NULL)
+    {
+      assume((q1!=NULL)&&(q2!=NULL));
+      if (pDeg(q,r) > ggt_deg)
+      {
+        choice=iter;
+        if (ggT != NULL)
+        {
+          p_LmFree(ggT, r);
+          p_LmFree(fp_p, r);
+          p_LmFree(fq_p, r);
+
+        }
+        ggt_deg = pDeg(q, r);
+        ggT = q;
+        fp_p = q1;
+        fq_p = q2;
+      }
+      else
+      {
+        p_LmFree(q, r);
+        p_LmFree(q1, r);
+        p_LmFree(q2, r);
+      }
+    }
+    iter=iter->next;
+  }
+  if(ggT!=NULL){
+
+    int dq =pTotaldegree(fq_p,r);
+    if (dq!=0){
+      fq=maPoly_InsertMonomial(mp, fq_p, r, NULL);
+      fp=maPoly_InsertMonomial(mp, fp_p, r, NULL);
+      return maPoly_InsertMonomial(mp, ggT, r, NULL);
+    }
+    else {
+      fq=NULL;
+      p_LmFree(fq_p, r);
+      p_LmFree(ggT, r);
+      fp=maPoly_InsertMonomial(mp, fp_p, r, NULL);
+      choice->ref++;
+      return choice;
+    }
+  }
+  else {
+    return NULL;
+  }
+
+
+}
+
+/********************************************************************
+ **                                                                 *
+ * maPoly_Optimize                                                  *
+ * adds and integrates subexpressions                               *
+ *******************************************************************/
+
+void maPoly_Optimize(mapoly mpoly, ring src_r){
+  assume(mpoly!=NULL && mpoly->src!=NULL);
+  mapoly iter = mpoly;
+  mapoly choice;
+  mapoly ggT=NULL;
+  mapoly fp=NULL;
+  mapoly fq=NULL;
+  while (iter->next!=NULL){
+    choice=iter->next;
+    if ((iter->f1==NULL)){
+      ggT=maFindBestggT(iter, choice, fp, fq,src_r);
+      if (choice!=NULL){
+        iter->f1=fp;
+        iter->f2=ggT;
+        if (fq!=NULL){
+          ggT->ref++;
+          choice->f1=fq;
+          choice->f2=ggT;
+        }
+      }
+
+    }
+    iter=iter->next;
+  }
+}
Index: kernel/fast_maps.h
===================================================================
--- kernel/fast_maps.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/fast_maps.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,106 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    fast_maps.cc
+ *  Purpose: implementation of fast maps
+ *  Author:  obachman (Olaf Bachmann), hannes (Hannes Schoenemann),
+ *           bricken (Michael Brickenstein) 
+ *  Created: 01/02
+ *  Version: $Id: fast_maps.h,v 1.1.1.1 2003-10-06 12:15:51 Singular Exp $
+ *******************************************************************/
+
+/*******************************************************************************
+**
+*S  mapoly, macoeff . . . . . . . . . . . . definition of structs/classes
+*/
+#ifndef FAST_MAPS_HEADER
+#define FAST_MAPS_HEADER
+class macoeff_s;
+class mapoly_s;
+class maideal_s;
+typedef class mapoly_s*  mapoly;
+typedef class macoeff_s* macoeff;
+typedef class maideal_s* maideal;
+
+class mapoly_s
+{
+public:
+  mapoly    next;
+  poly      src;        // monomial from WeightedRing
+  poly      dest;       // poly in CompRing
+  mapoly    f1, f2;     // if f1 != NULL && f2 != NULL then dest = f1*f2
+  int       ref;        // use to catch last usage to save last copy
+  macoeff   coeff;      // list of coeffs to use
+};
+
+class macoeff_s 
+{
+public:
+  macoeff       next;
+  number        n;
+  sBucket_pt    bucket;
+};
+
+class maideal_s
+{
+public:
+  int n;
+  sBucket_pt* buckets;
+};
+
+/*******************************************************************************
+**
+*S  definition of basic routines
+*/
+void maMonomial_Out(mapoly monomial, ring src_r, ring dest_r = NULL);
+void maPoly_Out(mapoly mpoly, ring src_ring, ring dest_r = NULL);
+
+// creates a new maMonomial
+// if bucket != NULL, a coeff with the bucket is created, as well
+mapoly maMonomial_Create(poly p, ring , sBucket_pt bucket = NULL);
+// unconditionally destroys a maMonomial:
+// src: LmFree 
+// dest: p_Delete 
+// coeffs: delete list
+void maMonomial_Destroy(mapoly monomial, ring src_r, ring dest_r = NULL);
+// decrements ref counter, if 0, calls Destroy
+inline mapoly maMonomial_Free(mapoly monomial, ring src_r, ring dest_r = NULL)
+{
+  monomial->ref--;
+  if (monomial->ref <= 0) 
+  { maMonomial_Destroy(monomial, src_r, dest_r); return NULL;}
+  return monomial;
+}
+
+// inserts ("adds") monomial what into poly into
+// returns the maMonomial which was inserted, or, if an equal one was found,
+// the monomial which "swalloed" the monomial
+// It furthermore might reset into
+mapoly maPoly_InsertMonomial(mapoly &into, mapoly what, ring src_r);
+mapoly maPoly_InsertMonomial(mapoly &into, poly p, ring src_r, sBucket_pt bucket = NULL);
+
+// optimizes mpoly for later evaluation
+void maPoly_Optimize(mapoly mpoly, ring src_r);
+
+// evaluates mpoly and destroys it, on the fly
+void maPoly_Eval(mapoly mpoly, ring src_r, ideal dest_id, ring dest_r, int total_cost);
+
+// creates mpoly and  mideal
+void maMap_CreatePolyIdeal(ideal map_id, ring map_r, 
+                           ring src_r, ring dest_r,
+                           mapoly &mp, maideal &mideal);
+// creates src_r: rings with weights
+//         dest_r: where we do our computations
+void maMap_CreateRings(ideal map_id, ring map_r, 
+                       ideal image_id, ring image_r, 
+                       ring &src_r, ring &dest_r, BOOLEAN &no_sort);
+
+// collects tthe results into an ideal and destroys maideal
+ideal maIdeal_2_Ideal(maideal ideal, ring dest_r);
+
+ideal fast_map(ideal map_id, ring map_r, ideal image_id, ring image_r);
+
+#endif
+
+
Index: kernel/feOpt.cc
===================================================================
--- kernel/feOpt.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/feOpt.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,554 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: feOpt.cc,v 1.1.1.1 2003-10-06 12:15:51 Singular Exp $ */
+/*
+* ABSTRACT: Implementation of option buisness
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include "mod2.h"
+#include "feOpt.h"
+
+// Define here which cmd-line options are recognized
+struct fe_option feOptSpec[] =
+{
+//
+//  Has to be of the form
+//    {name, has_arg, val,
+//     arg_name, help, type, value, set}
+//  where:
+//
+//        name   is the name of the long option.
+//
+//        has_arg
+//               is:  no_argument (or 0) if the option does not take
+//               an argument, required_argument (or 1) if the option
+//               requires  an  argument, or optional_argument (or 2)
+//               if the option takes an optional argument.
+//
+//        val    is  the  value  to  return,  or  to  load  into the
+//               variable pointed to by flag.
+//               NEEDS TO BE LONG_OPTION_RETURN, for long option
+//                           short option char,  for short option
+//
+//        arg_name if set, uses this value as name for argument in
+//                display of help
+//
+//        help  one-line description of option
+//
+//        type  one of feOptUntyped (value is never set),
+//                     feOptBool, feOptInt, feOptString
+//
+//        value (default) value of option
+//
+//       set   only relevant for feOptString:
+//             1: if value different from default value
+//             0: otherwise
+//
+// The order in which options are specified is the order in which
+// their help is printed on -h
+//
+// Options whose hel starts with an "//" are considered undocumented,
+// i.e., their help is not printed on -h
+//
+#if defined(ESINGULAR) || defined(TSINGULAR)
+#ifdef ESINGULAR
+// options only relevant for ESINGULAR
+  {"emacs",         required_argument,      LONG_OPTION_RETURN,
+   "EMACS",     "Use EMACS as emacs program to run Singular",          feOptString, 0,   0},
+
+  {"emacs-dir",         required_argument,  LONG_OPTION_RETURN,
+   "DIR",       "Use DIR as directory to look for emacs lisp files",   feOptString, 0,   0},
+
+  {"emacs-load",        required_argument,  LONG_OPTION_RETURN,
+   "FILE",      "Load FILE on emacs start-up, instead of default",     feOptString, 0,   0},
+#else
+  {"xterm",         required_argument,      LONG_OPTION_RETURN,
+   "XTERM",     "Use XTERM as terminal program to run Singular",          feOptString, 0,   0},
+#endif
+
+  {"singular",          required_argument,  LONG_OPTION_RETURN,
+   "PROG",      "Start PROG as Singular program within emacs",         feOptString, 0,   0},
+
+  {"no-call",     no_argument,        LONG_OPTION_RETURN,
+   0,          "Do not start program. Print call to stdout",       feOptBool,   0,   0},
+#endif
+
+#ifdef HAVE_MPSR
+  {"batch",             no_argument,        'b',
+   0,          "Run in MP batch mode",                                 feOptBool,    0,     0},
+#endif
+
+  {"execute",           required_argument,  'c',
+   "STRING",   "Execute STRING on start-up",                           feOptString, 0,   0},
+
+  {"sdb",               no_argument,        'd',
+   0,          "Enable source code debugger (experimental)",           feOptBool,    0,      0},
+
+  {"echo",              optional_argument,  'e',
+   "VAL",       "Set value of variable `echo' to (integer) VAL",        feOptInt,    0,      0},
+
+  {"help",              no_argument,        'h',
+   0,          "Print help message and exit",                          feOptUntyped,    0,      0},
+
+  {"quiet",             no_argument,        'q',
+   0,          "Do not print start-up banner and lib load messages",   feOptBool,    0,      0},
+  {"sort",             no_argument,        's',
+   0,          "// Sort NTL results",                                  feOptBool,    0,      0},
+
+  {"random",            required_argument,  'r',
+   "SEED",     "Seed random generator with integer (integer) SEED",    feOptInt,    0,      0},
+
+  {"no-tty",            no_argument,        't',
+   0,          "Do not redefine the terminal characteristics",         feOptBool,    0,      0},
+
+  {"user-option",       required_argument,  'u',
+   "STRING",   "Return STRING on `system(\"--user-option\")'",         feOptString, 0,   0},
+
+  {"version",           no_argument,        'v',
+   0,          "Print extended version and configuration info",        feOptUntyped,    0,      0},
+
+#ifdef HAVE_TCL
+  {"tclmode",           no_argument,        'x',
+   0,          "Run in TCL mode, i.e., with TCL user interface",       feOptBool,    0,      0},
+#endif
+
+  {"allow-net",         no_argument,        LONG_OPTION_RETURN,
+   0,          "Allow to fetch (html) help pages from the net",                feOptBool,    0,      0},
+
+  {"browser",           required_argument,  LONG_OPTION_RETURN,
+   "BROWSER",  "Display help in BROWSER ([x,tk]info, netscape)",       feOptString, 0,   0},
+
+#ifndef ESINGULAR
+  {"emacs",             no_argument,        LONG_OPTION_RETURN,
+   0,          "Set defaults for running within emacs",                feOptBool,    0,      0},
+#endif
+
+  {"no-stdlib",         no_argument,        LONG_OPTION_RETURN,
+   0,          "Do not load `standard.lib' on start-up",               feOptBool,    0,      0},
+
+  {"no-rc",             no_argument,        LONG_OPTION_RETURN,
+   0,          "Do not execute `.singularrc' file(s) on start-up",     feOptBool,    0,      0},
+
+  {"no-warn",           no_argument,        LONG_OPTION_RETURN,
+   0,          "Do not display warning messages",                      feOptBool,    0,      0},
+
+  {"no-out",            no_argument,        LONG_OPTION_RETURN,
+   0,          "Suppress all output",                                  feOptBool,    0,      0},
+
+  {"min-time",          required_argument,  LONG_OPTION_RETURN,
+  "SECS",     "Do not display times smaller than SECS (in seconds)",   feOptString, (void*) "0.5",  0},
+
+#ifdef HAVE_MPSR
+  {"MPport",           required_argument,   LONG_OPTION_RETURN,
+   "PORT",     "Use PORT number for MP conections",                    feOptString,    0,      0},
+
+  {"MPhost",           required_argument,   LONG_OPTION_RETURN,
+   "HOST",     "Use HOST for MP connections",                          feOptString,    0,   0},
+
+  {"MPrsh",           required_argument,   LONG_OPTION_RETURN,
+   "RSH",     "Use RSH for MP connections",                          feOptString,    0,   0},
+#endif
+
+  {"ticks-per-sec",     required_argument,  LONG_OPTION_RETURN,
+   "TICKS",     "Sets unit of timer to TICKS per second",               feOptInt,    (void*)1,      0},
+
+// undocumented options
+#ifdef HAVE_MPSR
+  {"MPtransp",         required_argument,   LONG_OPTION_RETURN,
+   "TRANSP",    "// Use TRANSP for MP connections",                     feOptString,    0,   0},
+
+  {"MPmode",           required_argument,   LONG_OPTION_RETURN,
+   "MODE",      "// Use MODE for MP connections",                       feOptString,    0,   0},
+#endif
+
+// terminator -- do NOT remove
+  { 0, 0, 0, 0, 0, feOptInt, 0, 0}
+};
+
+const char SHORT_OPTS_STRING[] = "bdhqstvxec:r:u:";
+
+//////////////////////////////////////////////////////////////
+//
+// Generation of feOptIndex
+//
+#ifdef GENERATE_OPTION_INDEX
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+main()
+{
+  FILE* fd;
+#ifdef ESINGULAR
+  fd = fopen("feOptES.inc", "w");
+#elif defined(TSINGULAR)
+  fd = fopen("feOptTS.inc", "w");
+#else
+  fd = fopen("feOpt.inc", "w");
+#endif
+
+  if (fd == NULL) exit(1);
+
+  int i = 0;
+
+  fputs("typedef enum\n{\n", fd);
+
+  while (feOptSpec[i].name != NULL)
+  {
+    const char* name = feOptSpec[i].name;
+    fputs("FE_OPT_", fd);
+    while (*name != 0)
+    {
+      if (*name == '-')
+      {
+        putc('_', fd);
+      }
+      else if (*name >= 97 && *name <= 122)
+      {
+        putc(*name - 32, fd);
+      }
+      else
+      {
+        putc(*name, fd);
+      }
+      name++;
+    }
+    if (i == 0)
+    {
+      fputs("=0", fd);
+    }
+    i++;
+    fputs(",\n  ", fd);
+  }
+
+  fprintf(fd, "FE_OPT_UNDEF\n} feOptIndex;\n");
+  fclose(fd);
+  exit(0);
+}
+
+#else // ! GENERATE_OPTION_INDEX
+
+///////////////////////////////////////////////////////////////
+//
+// Getting Values
+//
+
+feOptIndex feGetOptIndex(const char* name)
+{
+  int opt = 0;
+
+  while (opt != (int) FE_OPT_UNDEF)
+  {
+    if (strcmp(feOptSpec[opt].name, name) == 0)
+      return (feOptIndex) opt;
+    opt = opt + 1;
+  }
+  return FE_OPT_UNDEF;
+}
+
+feOptIndex feGetOptIndex(int optc)
+{
+  int opt = 0;
+
+  if (optc == LONG_OPTION_RETURN) return FE_OPT_UNDEF;
+
+  while (opt != (int) FE_OPT_UNDEF)
+  {
+    if (feOptSpec[opt].val == optc)
+      return (feOptIndex) opt;
+    opt = opt + 1;
+  }
+  return FE_OPT_UNDEF;
+}
+
+void* feGetOptValue(feOptIndex opt)
+{
+  return feOptSpec[(int)opt].value;
+}
+
+///////////////////////////////////////////////////////////////
+//
+// Setting Values
+//
+static void feOptHelp(const char* name);
+//
+// Return: NULL -- everything ok
+//         "error-string" on error
+#if !defined(ESINGULAR) && !defined(TSINGULAR)
+#include "omalloc.h"
+#include "febase.h"
+#include "ipshell.h"
+#include "tok.h"
+#include "sdb.h"
+#include "cntrlc.h"
+#include "timer.h"
+
+#ifdef HAVE_FACTORY
+#define SI_DONT_HAVE_GLOBAL_VARS
+#include <factory.h>
+#endif
+#include <errno.h>
+
+static char* feOptAction(feOptIndex opt);
+char* feSetOptValue(feOptIndex opt, char* optarg)
+{
+  if (opt == FE_OPT_UNDEF) return "option undefined";
+
+  if (feOptSpec[opt].type != feOptUntyped)
+  {
+    if (feOptSpec[opt].type != feOptString)
+    {
+      if (optarg != NULL)
+      {
+        errno = 0;
+        feOptSpec[opt].value = (void*) strtol(optarg, NULL, 10);
+        if (errno) return "invalid integer argument";
+      }
+      else
+      {
+        feOptSpec[opt].value = (void*) 0;
+      }
+    }
+    else
+    {
+      assume(feOptSpec[opt].type == feOptString);
+      if (feOptSpec[opt].set && feOptSpec[opt].value != NULL)
+        omFree(feOptSpec[opt].value);
+      if (optarg != NULL)
+        feOptSpec[opt].value = omStrDup(optarg);
+      else
+        feOptSpec[opt].value = NULL;
+      feOptSpec[opt].set = 1;
+    }
+  }
+  return feOptAction(opt);
+}
+
+char* feSetOptValue(feOptIndex opt, int optarg)
+{
+  if (opt == FE_OPT_UNDEF) return "option undefined";
+
+  if (feOptSpec[opt].type != feOptUntyped)
+  {
+    if (feOptSpec[opt].type == feOptString)
+      return "option value needs to be an integer";
+
+    feOptSpec[opt].value = (void*) optarg;
+  }
+  return feOptAction(opt);
+}
+
+static char* feOptAction(feOptIndex opt)
+{
+  // do some special actions
+  switch(opt)
+  {
+#ifdef HAVE_MPSR
+      case FE_OPT_BATCH:
+        if (feOptSpec[FE_OPT_BATCH].value)
+          fe_fgets_stdin=fe_fgets_dummy;
+        return NULL;
+#endif
+
+      case FE_OPT_HELP:
+        feOptHelp(feArgv0);
+        return NULL;
+
+      case FE_OPT_QUIET:
+        if (feOptSpec[FE_OPT_QUIET].value)
+          verbose &= ~(Sy_bit(0)|Sy_bit(V_LOAD_LIB));
+        else
+          verbose |= Sy_bit(V_LOAD_LIB)|Sy_bit(0);
+        return NULL;
+
+      case FE_OPT_NO_TTY:
+#if defined(HAVE_FEREAD) || defined(HAVE_READLINE)
+        if (feOptSpec[FE_OPT_NO_TTY].value)
+          fe_fgets_stdin=fe_fgets;
+#endif
+        return NULL;
+
+      case FE_OPT_SDB:
+      #ifdef HAVE_SDB
+        if (feOptSpec[FE_OPT_SDB].value)
+          sdb_flags = 1;
+        else
+          sdb_flags = 0;
+      #endif
+        return NULL;
+
+      case FE_OPT_VERSION:
+        printf(versionString());
+        return NULL;
+
+#ifdef HAVE_TCL
+      case FE_OPT_TCLMODE:
+        if (feOptSpec[FE_OPT_TCLMODE].value)
+        {
+          tclmode = TRUE;
+          fe_fgets_stdin=fe_fgets_tcl;
+          verbose|=Sy_bit(V_SHOW_MEM);
+        }
+        return NULL;
+#endif
+
+      case FE_OPT_ECHO:
+        si_echo = (int) feOptSpec[FE_OPT_ECHO].value;
+        if (si_echo < 0 || si_echo > 9)
+          return "argument of option is not in valid range 0..9";
+        return NULL;
+
+      case FE_OPT_RANDOM:
+        siRandomStart = (unsigned int) feOptSpec[FE_OPT_RANDOM].value;
+#ifdef buildin_rand
+        siSeed=siRandomStart;
+#else
+        srand((unsigned int)siRandomStart);
+#endif
+#ifdef HAVE_FACTORY
+        factoryseed(siRandomStart);
+#endif
+        return NULL;
+
+      case FE_OPT_EMACS:
+        if (feOptSpec[FE_OPT_EMACS].value)
+        {
+          // print EmacsDir and InfoFile so that Emacs
+          // mode can pcik it up
+          Warn("EmacsDir: %s", (feResource('e' /*"EmacsDir"*/) != NULL ?
+                                feResource('e' /*"EmacsDir"*/) : ""));
+          Warn("InfoFile: %s", (feResource('i' /*"InfoFile"*/) != NULL ?
+                                feResource('i' /*"InfoFile"*/) : ""));
+        }
+        return NULL;
+
+      case FE_OPT_NO_WARN:
+        if (feOptSpec[FE_OPT_NO_WARN].value)
+          feWarn = FALSE;
+        else
+          feWarn = TRUE;
+        return NULL;
+
+      case FE_OPT_NO_OUT:
+        if (feOptSpec[FE_OPT_NO_OUT].value)
+          feOut = FALSE;
+        else
+          feOut = TRUE;
+        return NULL;
+
+      case FE_OPT_MIN_TIME:
+      {
+        double mintime = atof((char*) feOptSpec[FE_OPT_MIN_TIME].value);
+        if (mintime <= 0) return "invalid float argument";
+        SetMinDisplayTime(mintime);
+        return NULL;
+      }
+
+      case FE_OPT_BROWSER:
+        feHelpBrowser((char*) feOptSpec[FE_OPT_BROWSER].value, 1);
+
+      case FE_OPT_TICKS_PER_SEC:
+      {
+        int ticks = (int) feOptSpec[FE_OPT_TICKS_PER_SEC].value;
+        if (ticks <= 0)
+          return "integer argument must be larger than 0";
+        SetTimerResolution(ticks);
+        return NULL;
+      }
+
+      default:
+        return NULL;
+  }
+}
+
+// Prints usage message
+void fePrintOptValues()
+{
+  int i = 0;
+
+  while (feOptSpec[i].name != 0)
+  {
+    if (feOptSpec[i].help != NULL && feOptSpec[i].type != feOptUntyped
+#ifndef NDEBUG
+        && *(feOptSpec[i].help) != '/'
+#endif
+        )
+    {
+      if (feOptSpec[i].type == feOptString)
+      {
+        if (feOptSpec[i].value == NULL)
+        {
+          Print("// --%-15s\n", feOptSpec[i].name);
+        }
+        else
+        {
+          Print("// --%-15s \"%s\"\n", feOptSpec[i].name, (char*) feOptSpec[i].value);
+        }
+      }
+      else
+      {
+        Print("// --%-15s %d\n", feOptSpec[i].name, feOptSpec[i].value);
+      }
+    }
+    i++;
+  }
+}
+
+#endif // ! ESingular
+
+// Prints help message
+static void feOptHelp(const char* name)
+{
+  int i = 0;
+  char tmp[20];
+#ifdef ESINGULAR
+  printf("ESingular: A Program that starts-up Singular within emacs, for\n");
+#endif
+  printf("Singular version %s -- a CAS for polynomial computations. Usage:\n", S_VERSION1);
+  printf("   %s [options] [file1 [file2 ...]]\n", name);
+  printf("Options:\n");
+
+  while (feOptSpec[i].name != 0)
+  {
+    if (feOptSpec[i].help != NULL
+#ifdef NDEBUG
+        && *(feOptSpec[i].help) != '/'
+#endif
+        )
+    {
+      if (feOptSpec[i].has_arg > 0)
+      {
+        if  (feOptSpec[i].has_arg > 1)
+          sprintf(tmp, "%s[=%s]", feOptSpec[i].name, feOptSpec[i].arg_name);
+        else
+          sprintf(tmp, "%s=%s", feOptSpec[i].name, feOptSpec[i].arg_name);
+
+        printf(" %c%c --%-19s %s\n",
+               (feOptSpec[i].val != 0 ? '-' : ' '),
+               (feOptSpec[i].val != 0 ? feOptSpec[i].val : ' '),
+               tmp,
+               feOptSpec[i].help);
+      }
+      else
+      {
+        printf(" %c%c --%-19s %s\n",
+               (feOptSpec[i].val != 0 ? '-' : ' '),
+               (feOptSpec[i].val != 0 ? feOptSpec[i].val : ' '),
+               feOptSpec[i].name,
+               feOptSpec[i].help);
+      }
+    }
+    i++;
+  }
+
+  printf("\nFor more information, type `help;' from within Singular or visit\n");
+  printf("http://www.singular.uni-kl.de or consult the\n");
+  printf("Singular manual (available as on-line info or html manual).\n");
+}
+
+
+
+#endif // GENERATE_OPTION_INDEX
Index: kernel/feOpt.h
===================================================================
--- kernel/feOpt.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/feOpt.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,89 @@
+#ifndef FEOPTS_H
+#define FEOPTS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: feOpt.h,v 1.1.1.1 2003-10-06 12:15:51 Singular Exp $ */
+/*
+* ABSTRACT: Declarations for working with Options
+*/
+
+#include "fegetopt.h"
+
+extern const char SHORT_OPTS_STRING[];
+#define LONG_OPTION_RETURN 13
+
+/* specifies format of options */
+extern struct fe_option feOptSpec[];
+
+#ifndef GENERATE_OPTION_INDEX
+
+/* provides feOptIndex enum type for fast accesses to feOptSpec */
+#if ! defined(GENTABLE) && ! defined(GENERATE_DEPEND)
+#ifdef ESINGULAR
+#include "feOptES.inc"
+#elif defined(TSINGULAR)
+#include "feOptTS.inc"
+#else
+#include "feOpt.inc"
+#endif
+#else
+typedef enum {FE_OPT_UNDEF}  feOptIndex;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void* feGetOptValue(feOptIndex opt);
+
+
+#ifdef __cplusplus
+}
+
+inline void* feOptValue(feOptIndex opt)
+{
+  return feOptSpec[(int)opt].value;
+}
+inline int feOptValue(feOptIndex opt, char** val)
+{
+  if (opt != FE_OPT_UNDEF && feOptSpec[(int)opt].type == feOptString)
+  {
+    *val = (char*) feOptSpec[(int)opt].value;
+    return TRUE;
+  }
+  *val = NULL;
+  return FALSE;
+}
+inline int feOptValue(feOptIndex opt, int* val)
+{
+  if (opt != FE_OPT_UNDEF && feOptSpec[(int)opt].type != feOptString)
+  {
+    *val = (int) feOptSpec[(int)opt].value;
+    return TRUE;
+  }
+  *val = 0;
+  return FALSE;
+}
+
+// maps name to otions
+feOptIndex feGetOptIndex(const char* name);
+feOptIndex feGetOptIndex(int optc);
+
+// Setting option values:
+// Return: NULL -- everything ok
+//         "error-string" on error
+
+// opt->type must be feOptInt or feOptBool
+char* feSetOptValue(feOptIndex opt, int optarg);
+// for opt->type != feOptString, optarg is converted
+// to an int
+char* feSetOptValue(feOptIndex opt, char* optarg);
+
+void fePrintOptValues();
+
+#endif /* __cplusplus */
+
+#endif /* ! GENERATE_OPTION_INDEX */
+
+#endif /*  FEOPTS_H */
Index: kernel/feResource.cc
===================================================================
--- kernel/feResource.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/feResource.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,779 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: feResource.cc,v 1.1.1.1 2003-10-06 12:15:52 Singular Exp $ */
+/*
+* ABSTRACT: management of resources
+*/
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "mod2.h"
+#ifdef AIX_4
+#define HAVE_PUTENV 1
+#endif
+
+#include "distrib.h"
+#include "dError.h"
+#if !defined(ESINGULAR) && !defined(TSINGULAR)
+#include "febase.h"
+#include "omalloc.h"
+#else
+char* feResource(const char id, int warn = -1);
+char* feResource(const char* key, int warn = -1);
+#include "dError.c"
+#endif
+
+// define RESOURCE_DEBUG for chattering about resource management
+// #define RESOURCE_DEBUG
+
+#if defined(MAKE_DISTRIBUTION)
+#if defined(ix86_Win) && ! defined(__CYGWIN__)
+#define SINGULAR_DEFAULT_DIR "/Singular/"S_VERSION1
+#elif defined(macintosh)
+#define SINGULAR_DEFAULT_DIR "Macintosh HD:Singular:"S_VERSION1
+#else // unix
+#define SINGULAR_DEFAULT_DIR "/usr/local/Singular/"S_VERSION1
+#endif
+#else // ! defined(MAKE_DISTRIBUTION)
+#define SINGULAR_DEFAULT_DIR S_ROOT_DIR
+#endif // defined(MAKE_DISTRIBUTION)
+
+/*****************************************************************
+ *
+ * Declarations: Data  structures
+ *
+ *****************************************************************/
+typedef enum {feResUndef = 0, feResBinary, feResDir, feResFile, feResUrl, feResPath} feResourceType;
+
+typedef struct feResourceConfig_s
+{
+  char*           key;   // key to identify resource
+  char            id;    // char id to identify resource
+  feResourceType  type;  // type of Resource
+  char*           env;   // env variable to look for
+  char*           fmt;   // format string -- see below for epxlaination
+  char*                        value; // what it was set to
+} feResourceConfig_s;
+typedef feResourceConfig_s * feResourceConfig;
+
+// feSprintf transforms format strings as follows:
+// 1.) substrings of the form %c (c being a letter) are replaced by respective resource value
+// 2.) substrings of the form $string are replaced by value of resp. env variable
+
+// feCleanResource makes furthermore  the following transformations (except for URL resources)
+// 1.) '/' characters are replaced by respective directory - separators
+// 2.) ';' characters are replaced by respective path separators
+static feResourceConfig_s feResourceConfigs[25] =
+{
+  {"SearchPath",    's',     feResPath,  NULL,
+   "$SINGULARPATH;"
+   "%b/LIB;"
+   "%r/LIB;"
+   "%r/../LIB;"
+   "%d/LIB;"
+   "%d/../LIB"
+   ""},
+#ifdef HAVE_PLURAL
+  {"Singular",  'S',    feResBinary,"SINGULAR_EXECUTABLE",  "%d/"S_UNAME"/Plural",""},
+#else
+  {"Singular",  'S',    feResBinary,"SINGULAR_EXECUTABLE",  "%d/"S_UNAME"/Singular",""},
+#endif
+  {"BinDir",    'b',    feResDir,   "SINGULAR_BIN_DIR",     "%d/"S_UNAME            ""},
+  {"RootDir",   'r',    feResDir,   "SINGULAR_ROOT_DIR",    "%b/..",                ""},
+  {"DefaultDir",'d',    feResDir,   "SINGULAR_DEFAULT_DIR",  SINGULAR_DEFAULT_DIR,  ""},
+#ifdef HAVE_PLURAL
+  {"InfoFile",  'i',    feResFile,  "SINGULAR_INFO_FILE",   "%r/info/plural.hlp", ""},
+  {"IdxFile",   'x',    feResFile,  "SINGULAR_IDX_FILE",    "%r/doc/plural.idx",  ""},
+#else
+  {"InfoFile",  'i',    feResFile,  "SINGULAR_INFO_FILE",   "%r/info/singular.hlp", ""},
+  {"IdxFile",   'x',    feResFile,  "SINGULAR_IDX_FILE",    "%r/doc/singular.idx",  ""},
+#endif
+  {"HtmlDir",   'h',    feResDir,   "SINGULAR_HTML_DIR",    "%r/html",              ""},
+#ifdef HAVE_PLURAL
+  {"ManualUrl", 'u',    feResUrl,   "SINGULAR_URL",         "http://www.singular.uni-kl.de/plural/Manual/"S_VERSION1,    ""},
+#else
+  {"ManualUrl", 'u',    feResUrl,   "SINGULAR_URL",         "http://www.singular.uni-kl.de/Manual/"S_VERSION1,    ""},
+#endif
+  {"ExDir",      'm',   feResDir,   "SINGULAR_EXAMPLES_DIR","%r/examples",              ""},
+#if !defined(macintosh)
+  {"netscape",  'N',    feResBinary,"NETSCAPE",             "%b/netscape",          ""},
+  {"info",      'I',    feResBinary,"INFO",                 "%b/info",              ""},
+  {"tkinfo",    'T',    feResBinary,"TKINFO",               "%b/tkinfo",            ""},
+#ifdef ix86_Win
+  {"rxvt",     'X',    feResBinary,"RXVT",                "%b/rxvt",             ""},
+#else
+  {"xterm",     'X',    feResBinary,"XTERM",                "%b/xterm",             ""},
+#endif
+  {"Path",      'p',    feResPath,  NULL,                   "%b;$PATH",         ""},
+#endif // ! defined(macintosh)
+
+#ifdef ESINGULAR
+  {"emacs",    'E',    feResBinary, "ESINGULAR_EMACS",      "%b/emacs",              ""},
+  {"xemacs",    'A',    feResBinary, "ESINGULAR_EMACS",      "%b/xemacs",              ""},
+#ifdef HAVE_PLURAL
+  {"SingularEmacs",'M',feResBinary, "ESINGULAR_SINGULAR",    "%b/Plural",           ""},
+#else
+  {"SingularEmacs",'M',feResBinary, "ESINGULAR_SINGULAR",    "%b/Singular",           ""},
+#endif
+  {"EmacsLoad",'l',    feResFile,   "ESINGULAR_EMACS_LOAD",  "%e/.emacs-singular",             ""},
+  {"EmacsDir",  'e',    feResDir,   "ESINGULAR_EMACS_DIR",   "%r/emacs",             ""},
+#elif defined(TSINGULAR)
+#ifdef HAVE_PLURAL
+  {"SingularXterm",'M',feResBinary, "TSINGULAR_SINGULAR",    "%b/Plural",           ""},
+#else
+  {"SingularXterm",'M',feResBinary, "TSINGULAR_SINGULAR",    "%b/Singular",           ""},
+#endif
+#else
+  {"EmacsDir",  'e',    feResDir,   "SINGULAR_EMACS_DIR",   "%r/emacs",             ""},
+#endif
+  {NULL, 0, feResUndef, NULL, NULL, NULL}, // must be the last record
+};
+
+
+/*****************************************************************
+ *
+ * Declarations: Local variables / functions
+ *
+ *****************************************************************/
+char* feArgv0=NULL;
+#define MAXRESOURCELEN 5*MAXPATHLEN
+
+char fePathSep =
+#if defined(ix86_Win)
+';'
+#elif defined(macintosh)
+','
+#else
+':'
+#endif
+;
+
+static feResourceConfig feGetResourceConfig(const char id);
+static feResourceConfig feGetResourceConfig(const char* key);
+static char* feResource(feResourceConfig config, int warn);
+static char* feResourceDefault(feResourceConfig config);
+static char* feInitResource(feResourceConfig config, int warn);
+static char* feGetExpandedExecutable();
+static BOOLEAN feVerifyResourceValue(feResourceType type, char* value);
+static char* feCleanResourceValue(feResourceType type, char* value);
+static char* feCleanUpFile(char* fname);
+static char* feCleanUpPath(char* path);
+static void mystrcpy(char* d, char* s);
+static char* feSprintf(char* s, const char* fmt, int warn = -1);
+#if defined(ix86_Win) && defined(__GNUC__)
+// utility function of Cygwin32:
+extern "C" int cygwin32_posix_path_list_p (const char *path);
+#endif
+
+/*****************************************************************
+ *
+ * Public functions
+ *
+ *****************************************************************/
+char* feResource(const char* key, int warn)
+{
+  return feResource(feGetResourceConfig(key), warn);
+}
+
+char* feGetResource(const char id)
+{
+  return feResource(feGetResourceConfig(id), -1);
+}
+
+char* feResource(const char id, int warn)
+{
+  return feResource(feGetResourceConfig(id), warn);
+}
+
+char* feResourceDefault(const char id)
+{
+  return feResourceDefault(feGetResourceConfig(id));
+}
+
+char* feResourceDefault(const char* key)
+{
+  return feResourceDefault(feGetResourceConfig(key));
+}
+
+void feInitResources(char* argv0)
+{
+#if defined(ix86_Win) && defined(__GNUC__)
+  if (cygwin32_posix_path_list_p (getenv("PATH")))
+    fePathSep = ':';
+#endif
+  feArgv0 = omStrDup(argv0);
+#ifdef RESOURCE_DEBUG
+  printf("feInitResources: entering with argv0=%s=\n", argv0);
+#endif
+  // init some Resources
+  feResource('b');
+  feResource('r');
+  // don't complain about stuff when initializing SingularPath
+  feResource('s',0);
+
+#if defined(HAVE_SETENV) || defined(HAVE_PUTENV)
+  char* path = feResource('p');
+#ifdef RESOURCE_DEBUG
+  printf("feInitResources: setting path with argv0=%s=\n", path);
+#endif
+#ifdef HAVE_PUTENV
+  if (path != NULL) { char *s=(char *)omAlloc0(strlen(path)+6);
+                      sprintf(s,"PATH=%s",path);
+                      putenv(s);
+                    }
+#else
+  if (path != NULL) setenv("PATH", path, 1);
+#endif
+#endif
+}
+
+void feReInitResources()
+{
+  int i = 0;
+  while (feResourceConfigs[i].key != NULL)
+  {
+    if (feResourceConfigs[i].value != "")
+    {
+      if (feResourceConfigs[i].value != NULL)
+        omFree(feResourceConfigs[i].value);
+      feResourceConfigs[i].value = "";
+    }
+    i++;
+  }
+#ifdef RESOURCE_DEBUG
+  printf("feInitResources: entering with argv0=%s=\n", feArgv0);
+#endif
+  // init some Resources
+  feResource('b');
+  feResource('r');
+  // don't complain about stuff when initializing SingularPath
+  feResource('s',0);
+}
+
+/*****************************************************************
+ *
+ * Local functions
+ *
+ *****************************************************************/
+static feResourceConfig feGetResourceConfig(const char id)
+{
+  int i = 0;
+  while (feResourceConfigs[i].key != NULL)
+  {
+    if (feResourceConfigs[i].id == id) return &(feResourceConfigs[i]);
+    i++;
+  }
+  return NULL;
+}
+
+static feResourceConfig feGetResourceConfig(const char* key)
+{
+  int i = 0;
+  while (feResourceConfigs[i].key != NULL)
+  {
+    if (strcmp(feResourceConfigs[i].key, key) == 0)
+      return &(feResourceConfigs[i]);
+    i++;
+  }
+  return NULL;
+}
+
+static char* feResource(feResourceConfig config, int warn)
+{
+  if (config == NULL) return NULL;
+  if (config->value != NULL && *(config->value) != '\0') return config->value;
+  return feInitResource(config, warn);
+}
+
+static char* feResourceDefault(feResourceConfig config)
+{
+  if (config == NULL) return NULL;
+  char* value = (char*) omAlloc(MAXRESOURCELEN);
+  feSprintf(value, config->fmt, -1);
+  return value;
+}
+
+static char* feInitResource(feResourceConfig config, int warn)
+{
+  assume(config != NULL);
+#ifdef RESOURCE_DEBUG
+  printf("feInitResource: entering for %s\n", config->key);
+#endif
+
+  char value[MAXRESOURCELEN];
+  // now we have to work
+  // First, check Environment variable
+  if (config->env != NULL)
+  {
+    char* evalue = getenv(config->env);
+    if (evalue != NULL)
+    {
+#ifdef RESOURCE_DEBUG
+      printf("feInitResource: Found value from env:%s\n", evalue);
+#endif
+      strcpy(value, evalue);
+      if (config->type == feResBinary  // do not verify binaries
+          ||
+          feVerifyResourceValue(config->type,
+                                feCleanResourceValue(config->type, value)))
+      {
+#ifdef RESOURCE_DEBUG
+        printf("feInitResource: Set value of %s to =%s=\n", config->key, value);
+#endif
+        config->value = omStrDup(value);
+        return config->value;
+      }
+    }
+  }
+
+  *value = '\0';
+  // Special treatment of executable
+  if (config->id == 'S')
+  {
+    char* executable = feGetExpandedExecutable();
+    if (executable != NULL)
+    {
+#ifdef RESOURCE_DEBUG
+      printf("exec:%s\n", executable);
+#endif
+      strcpy(value, executable);
+#ifdef RESOURCE_DEBUG
+      printf("value:%s\n", value);
+#endif
+      omFree(executable);
+    }
+  }
+  // and bindir
+  else if (config->id == 'b')
+  {
+    char* executable = feResource('S');
+#ifdef RESOURCE_DEBUG
+      printf("feInitResource: Get %s from %s\n", config->key, executable);
+#endif
+    if (executable != NULL)
+    {
+      strcpy(value, executable);
+      executable = strrchr(value, DIR_SEP);
+      if (executable != NULL) *executable = '\0';
+    }
+  }
+
+#ifdef RESOURCE_DEBUG
+  printf("value:%s\n", value);
+#endif
+
+  if (*value == '\0' && config->fmt != NULL )
+  {
+    feSprintf(value, config->fmt, warn);
+  }
+  else if (config->fmt == NULL)
+  {
+    sprintf(value, "Wrong Resource Specification of %s", config->key);
+    dReportBug(value);
+    return NULL;
+  }
+
+  // Clean and verify
+  if (feVerifyResourceValue(config->type,
+                            feCleanResourceValue(config->type, value)))
+  {
+#ifdef RESOURCE_DEBUG
+    printf("feInitResource: Set value of %s to =%s=\n", config->key, value);
+#endif
+    config->value = omStrDup(value);
+    return config->value;
+  }
+  else if (config->type == feResBinary)
+  {
+    // for binaries, search through PATH once more
+    char* executable = omFindExec(config->key, value);
+    if (executable != NULL)
+    {
+      if (feVerifyResourceValue(config->type,
+                                feCleanResourceValue(config->type, value)))
+      {
+        config->value = omStrDup(value);
+#ifdef RESOURCE_DEBUG
+        printf("feInitResource: Set value of %s to =%s=\n", config->key, config->value);
+#endif
+        return config->value;
+      }
+    }
+  }
+
+  // issue warning if explicitely requested, or if
+  // this value is gotten for the first time
+  if (warn > 0 || (warn < 0 && config->value != NULL))
+  {
+    Warn("Could not get %s. ", config->key);
+    Warn("Either set environment variable %s to %s,",
+         config->env, config->key);
+    feSprintf(value, config->fmt, warn);
+    Warn("or make sure that %s is at %s", config->key, value);
+  }
+#ifdef RESOURCE_DEBUG
+      printf("feInitResource: Set value of %s to NULL", config->key);
+#endif
+  config->value = NULL;
+  return NULL;
+}
+
+static char* feGetExpandedExecutable()
+{
+  if (feArgv0 == NULL || *feArgv0 == '\0')
+  {
+    if (feArgv0 == NULL) dReportBug("feArgv0 == NULL");
+    else dReportBug("feArgv0 == ''");
+    return NULL;
+  }
+#ifndef macintosh
+#ifdef ix86_Win // stupid WINNT sometimes gives you argv[0] within ""
+  if (*feArgv0 == '"')
+  {
+    int l = strlen(feArgv0);
+    if (feArgv0[l-1] == '"')
+    {
+      feArgv0[l-1] = '\0';
+      feArgv0++;
+    }
+  }
+#endif
+#ifdef RESOURCE_DEBUG
+  printf("feGetExpandedExecutable: calling find_exec with =%s=\n", feArgv0);
+#endif
+  char executable[MAXRESOURCELEN];
+  char* value = omFindExec(feArgv0, executable);
+#ifdef RESOURCE_DEBUG
+  printf("feGetExpandedExecutable: find_exec exited with =%s=%d\n", executable, access(executable, X_OK));
+#endif
+  if (value == NULL)
+  {
+    char message[MAXRESOURCELEN];
+    sprintf(message, "Could not get expanded executable from %s", feArgv0);
+    dReportBug(message);
+    return NULL;
+  }
+  return omStrDup(value);
+#else // macintosh
+  return feArgv0;
+#endif
+}
+
+
+static BOOLEAN feVerifyResourceValue(feResourceType type, char* value)
+{
+#ifdef RESOURCE_DEBUG
+  printf("feVerifyResourceValue: entering with =%s=\n", value);
+  printf("%d:%d\n", access(value, R_OK), access(value, X_OK));
+#endif
+  switch(type)
+  {
+      case feResUrl:
+      case feResPath:
+        return TRUE;
+
+      case feResFile:
+        return ! access(value, R_OK);
+
+      case feResBinary:
+      case feResDir:
+        return ! access(value, X_OK);
+
+      default:
+        return FALSE;
+  }
+}
+
+/*****************************************************************
+ *
+ * Cleaning/Transformations of resource values
+ *
+ *****************************************************************/
+
+static char* feCleanResourceValue(feResourceType type, char* value)
+{
+  if (value == NULL || *value == '\0') return value;
+#ifdef RESOURCE_DEBUG
+      printf("Clean value:%s\n", value);
+#endif
+#ifdef ix86_Win
+#ifdef RESOURCE_DEBUG
+      printf("Clean WINNT value:%s\n", value);
+#endif
+  if (type == feResBinary)
+  {
+    int l = strlen(value);
+    if (l < 4 || (strcmp(&value[l-4], ".exe") != 0 &&
+                  strcmp(&value[l-4], ".EXE") != 0))
+      strcat(value, ".exe");
+  }
+#endif
+  if (type == feResFile || type == feResBinary || type == feResDir)
+    return feCleanUpFile(value);
+  if (type == feResPath)
+    return feCleanUpPath(value);
+  return value;
+}
+
+static char* feCleanUpFile(char* fname)
+{
+  char* fn, *s;
+
+#ifdef RESOURCE_DEBUG
+  printf("feCleanUpFile: entering with =%s=\n", fname);
+#endif
+  // Remove unnecessary .. and //
+  for (fn = fname; *fn != '\0'; fn++)
+  {
+    if (*fn == '/')
+    {
+      if (*(fn+1) == '\0')
+      {
+        if (fname != fn) *fn = '\0';
+        break;
+      }
+      if (*(fn + 1) == '/' && (fname != fn))
+      {
+        mystrcpy(fn, fn+1);
+        fn--;
+      }
+      else if (*(fn+1) == '.')
+      {
+        if (*(fn+2) == '.' && (*(fn + 3) == '/' || *(fn + 3) == '\0'))
+        {
+          *fn = '\0';
+          s = strrchr(fname, '/');
+          if (s != NULL)
+          {
+            mystrcpy(s+1, fn + (*(fn + 3) != '\0' ? 4 : 3));
+            fn = s-1;
+          }
+          else
+          {
+            *fn = '/';
+          }
+        }
+        else if (*(fn+2) == '/' || *(fn+2) == '\0')
+        {
+          mystrcpy(fn+1, fn+3);
+          fn--;
+        }
+      }
+    }
+  }
+
+#ifdef macintosh
+  // replace / and .. by DIR_SEP and UP_DIR
+  fn = fname;
+  while (*fn != NULL)
+  {
+    if (*fn == '.' && *(fn + 1) == '.')
+    {
+      mystrcpy(fn , fn + 2);
+    }
+    else
+    {
+      if (*fn == '/') *fn = DIR_SEP;
+      fn++;
+    }
+  }
+#endif
+
+#ifdef RESOURCE_DEBUG
+  printf("feCleanUpFile: leaving with =%s=\n", fname);
+#endif
+  return fname;
+}
+
+// remove duplicates dir resp. those which do not exist
+static char* feCleanUpPath(char* path)
+{
+#ifdef RESOURCE_DEBUG
+  printf("feCleanUpPath: entering with: =%s=\n", path);
+#endif
+  if (path == NULL) return path;
+
+  int n_comps = 1, i, j;
+  char* opath = path;
+  char** path_comps;
+
+  for (; *path != '\0'; path++)
+  {
+    if (*path == fePathSep) n_comps++;
+    if (*path == ';')
+    {
+      *path = fePathSep;
+      n_comps++;
+    }
+  }
+
+  path_comps = (char**) omAlloc(n_comps*sizeof(char*));
+  path_comps[0]=opath;
+  path=opath;
+  i = 1;
+
+  if (i < n_comps)
+  {
+    while (1)
+    {
+      if (*path == fePathSep)
+      {
+        *path = '\0';
+        path_comps[i] = path+1;
+        i++;
+        if (i == n_comps) break;
+      }
+      path++;
+    }
+  }
+
+  for (i=0; i<n_comps; i++)
+    path_comps[i] = feCleanUpFile(path_comps[i]);
+#ifdef RESOURCE_DEBUG
+  PrintS("feCleanUpPath: after CleanUpName: ");
+  for (i=0; i<n_comps; i++)
+    Print("%s:", path_comps[i]);
+  Print("\n");
+#endif
+
+  for (i=0; i<n_comps;)
+  {
+#ifdef RESOURCE_DEBUG
+    if (access(path_comps[i], X_OK | R_OK))
+      Print("feCleanUpPath: remove %d:%s -- can not access\n", i, path_comps[i]);
+#endif
+    if ( ! access(path_comps[i], X_OK | R_OK))
+    {
+      // x- permission is granted -- we assume that it is a dir
+      for (j=0; j<i; j++)
+      {
+        if (strcmp(path_comps[j], path_comps[i]) == 0)
+        {
+          // found a duplicate
+#ifdef RESOURCE_DEBUG
+          Print("feCleanUpPath: remove %d:%s -- equal to %d:%s\n", j, path_comps[j], i, path_comps[i]);
+#endif
+          j = i+1;
+          break;
+        }
+      }
+      if (j == i)
+      {
+        i++;
+        continue;
+      }
+    }
+    // now we can either not access or found a duplicate
+    path_comps[i] = NULL;
+    for (j=i+1; j<n_comps; j++)
+        path_comps[j-1] = path_comps[j];
+    n_comps--;
+  }
+
+
+  // assemble everything again
+  for (path=opath, i=0;i<n_comps-1;i++)
+  {
+    strcpy(path, path_comps[i]);
+    path += strlen(path);
+    *path = fePathSep;
+    path++;
+  }
+  if (n_comps)
+  {
+    strcpy(path, path_comps[i]);
+  }
+  else
+  {
+    *opath = '\0';
+  }
+  omFree(path_comps);
+#ifdef RESOURCE_DEBUG
+  Print("feCleanUpPath: leaving with path=%s=\n", opath);
+#endif
+  return opath;
+}
+
+// strcpy where source and destination may overlap
+static void mystrcpy(char* d, char* s)
+{
+  assume(d != NULL && s != NULL);
+  while (*s != '\0')
+  {
+    *d = *s;
+    d++;
+    s++;
+  }
+  *d = '\0';
+}
+
+/*****************************************************************
+ *
+ * feSprintf
+ *
+ *****************************************************************/
+static char* feSprintf(char* s, const char* fmt, int warn)
+{
+  char* s_in = s;
+  if (fmt == NULL) return NULL;
+
+  while (*fmt != '\0')
+  {
+    *s = *fmt;
+
+    if (*fmt == '%' && *(fmt + 1) != '\0')
+    {
+      fmt++;
+      char* r = feResource(*fmt, warn);
+      if (r != NULL)
+      {
+        strcpy(s, r);
+        s += strlen(r) - 1;
+      }
+      else
+      {
+        s++;
+        *s = *fmt;
+      }
+    }
+    else if (*fmt == '$' && *(fmt + 1) != '\0')
+    {
+      fmt++;
+      char* v = s + 1;
+      while (*fmt == '_' ||
+             (*fmt >= 'A' && *fmt <= 'Z') ||
+             (*fmt >= 'a' && *fmt <= 'z'))
+      {
+        *v = *fmt;
+        v++;
+        fmt++;
+      }
+      fmt--;
+      *v = '\0';
+      v = getenv(s + 1);
+      if (v != NULL) strcpy(s, v);
+      s += strlen(s) - 1;
+    }
+    s++;
+    fmt++;
+  }
+  *s = '\0';
+  return s_in;
+}
+
+void feStringAppendResources(int warn)
+{
+  int i = 0;
+  char* r;
+  StringAppend("%-10s:\t%s\n", "argv[0]", feArgv0);
+  while (feResourceConfigs[i].key != NULL)
+  {
+    r = feResource(feResourceConfigs[i].key, warn);
+    StringAppend("%-10s:\t%s\n", feResourceConfigs[i].key,
+                 (r != NULL ? r : ""));
+    i++;
+  }
+}
Index: kernel/febase.cc
===================================================================
--- kernel/febase.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/febase.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1316 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: febase.cc,v 1.1.1.1 2003-10-06 12:15:52 Singular Exp $ */
+/*
+* ABSTRACT: i/o system
+*/
+
+/* I need myfread in standalone_parser */
+#ifndef STANDALONE_PARSER
+#include "mod2.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <mylimits.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#ifndef __MWERKS__
+#include <unistd.h>
+#endif
+#ifdef NeXT
+#include <sys/file.h>
+#endif
+#ifdef ix86_Linux_libc5
+#undef stdin
+extern FILE *stdin;
+#endif
+
+#ifdef HAVE_PWD_H
+#include "pwd.h"
+#endif
+
+#include "febase.h"
+#include "omalloc.h"
+#include "dError.h"
+#include "../Singular/ipshell.h"
+
+#define fePutChar(c) fputc((uchar)(c),stdout)
+/*0 implementation */
+
+char fe_promptstr[]
+#ifdef macintosh
+                   =" \n";
+#else
+                   ="  ";
+#endif
+
+#define INITIAL_PRINT_BUFFER 24*1024
+static int feBufferLength=INITIAL_PRINT_BUFFER;
+static char * feBuffer=(char *)omAlloc(INITIAL_PRINT_BUFFER);
+
+int     si_echo = 0;
+int     printlevel = 0;
+#ifndef macintosh
+int     pagelength = 24;
+#else
+int     pagelength = -1;
+#endif
+int     colmax = 80;
+char    prompt_char = '>'; /*1 either '>' or '.'*/
+extern "C" {
+BITSET  verbose = 1
+                  | Sy_bit(V_REDEFINE)
+                  | Sy_bit(V_LOAD_LIB)
+                  | Sy_bit(V_SHOW_USE)
+                  | Sy_bit(V_PROMPT)
+/*                  | Sy_bit(V_DEBUG_MEM) */
+;}
+BOOLEAN errorreported = FALSE;
+char *  feErrors=NULL;
+int     feErrorsLen=0;
+BOOLEAN feWarn = TRUE;
+BOOLEAN feOut = TRUE;
+
+#ifdef macintosh
+static  int lines = 0;
+static  int cols = 0;
+#endif
+
+const char feNotImplemented[]="not implemented";
+
+BOOLEAN feProt = FALSE;
+FILE*   feProtFile;
+BOOLEAN tclmode=FALSE;
+/* TCL-Protocoll (Singular -x): <char type>:<int length>:<string> \n
+*  E:l:s  error
+*  W:l:s  warning
+*  N:l:s  stdout
+*  Q:0:   quit
+*  P:l:   prompt > (ring defined)
+*  U:l:   prompt > (no ring defined)
+*  P:l:   prompt .
+*  R:l:<ring-name> ring change
+*  L:l:<lib name> library loaded
+*  O:l:<list of options(space seperated)> option change
+*  M:l:<mem-usage> output from "option(mem)"
+*/
+
+
+/**************************************************************************
+* handling of 'voices'
+**************************************************************************/
+
+extern int blocknest; /* scaner.l internal */
+
+int    yy_noeof=0;     // the scanner "state"
+int    yy_blocklineno; // to get the lineno of the block start from scanner
+Voice  *currentVoice = NULL;
+FILE   *feFilePending; /*temp. storage for grammar.y */
+
+static char * BT_name[]={"BT_none","BT_break","BT_proc","BT_example",
+                       "BT_file","BT_execute","BT_if","BT_else"};
+/*2
+* the name of the current 'Voice': the procname (or filename)
+*/
+const char * VoiceName()
+{
+  if ((currentVoice!=NULL)
+  && (currentVoice->filename!=NULL))
+    return currentVoice->filename;
+  return sNoName;
+}
+
+/*2
+* the calling chain of Voices
+*/
+void VoiceBackTrack()
+{
+  Voice *p=currentVoice;
+  while (p->prev!=NULL)
+  {
+    p=p->prev;
+    char *s=p->filename;
+    if (s==NULL)
+      PrintS("-- called from ? --\n");
+    else
+      Print("-- called from %s --\n",s);
+  }
+}
+
+/*2
+* init a new voice similiar to the current
+*/
+void Voice::Next()
+{
+  Voice *p=new Voice;
+  // OB: ???
+  // Hmm... when Singular is used as batch file
+  // then this voice is never freed
+  omMarkAsStaticAddr(p);
+  if (currentVoice != NULL)
+  {
+    currentVoice->curr_lineno=yylineno;
+    currentVoice->next=p;
+  }
+  p->prev=currentVoice;
+  currentVoice=p;
+  //Print("Next:");
+}
+
+feBufferTypes Voice::Typ()
+{
+  switch(typ)
+  {
+    case BT_proc:
+    case BT_example:
+    case BT_file:
+      return typ;
+    default:
+      if (prev==NULL) return (feBufferTypes)0;
+      return prev->Typ();
+  }
+}
+
+/*2
+* start the file 'fname' (STDIN is stdin) as a new voice (cf.VFile)
+* return FALSE on success, TRUE if an error occurs (file cannot be opened)
+*/
+BOOLEAN newFile(char *fname,FILE* f)
+{
+  currentVoice->Next();
+  //Print(":File%d(%s):%s(%x)\n",
+  //  currentVoice->typ,BT_name[currentVoice->typ],fname,currentVoice);
+  currentVoice->filename   = omStrDup(fname);
+  omMarkAsStaticAddr(currentVoice->filename);
+  if (strcmp(fname,"STDIN") == 0)
+  {
+    currentVoice->files = stdin;
+    currentVoice->sw = BI_stdin;
+    currentVoice->start_lineno = 1;
+  }
+  else
+  {
+    currentVoice->sw = BI_file; /* needed by exitVoice below */
+    if (f!=NULL)
+      currentVoice->files = f;
+    else
+    {
+      currentVoice->files = feFopen(fname,"r",NULL,TRUE);
+      if (currentVoice->files==NULL)
+      {
+        exitVoice();
+        return TRUE;
+      }
+    }
+    currentVoice->start_lineno = 0;
+  }
+  yylineno=currentVoice->start_lineno;
+  //Voice *p=currentVoice;
+  //Print("-----------------\ncurr:");
+  //do
+  //{
+  //Print("voice fn:%s\n",p->filename);
+  //p=p->prev;
+  //}
+  //while (p!=NULL);
+  //Print("----------------\n");
+  return FALSE;
+}
+
+void newBuffer(char* s, feBufferTypes t, procinfo* pi, int lineno)
+{
+  currentVoice->Next();
+  //Print(":Buffer%d(%s):%s(%x)\n",
+  //  t,BT_name[t],pname,currentVoice);
+  if (pi!=NULL)
+  {
+    int l=strlen(pi->procname);
+    if (pi->libname!=NULL) l+=strlen(pi->libname);
+    currentVoice->filename = (char *)omAlloc(l+3);
+    *currentVoice->filename='\0';
+    if (pi->libname!=NULL) strcat(currentVoice->filename,pi->libname);
+    strcat(currentVoice->filename,"::");
+    strcat(currentVoice->filename,pi->procname);
+    currentVoice->pi       = pi;
+  }
+  else
+  {
+    currentVoice->filename = omStrDup(currentVoice->prev->filename);
+    currentVoice->pi       = currentVoice->prev->pi;
+  }
+  currentVoice->buffer   = s;
+  currentVoice->sw       = BI_buffer;
+  currentVoice->typ      = t;
+  switch (t)
+  {
+    case BT_execute:
+                     yylineno-=2;
+                     break;
+    case BT_proc:
+    case BT_example:
+                     currentVoice->oldb=myynewbuffer();
+                     yylineno = lineno+1;
+                     break;
+    case BT_if:
+    case BT_else:
+    case BT_break:
+                     yylineno = yy_blocklineno-1;
+                     break;
+    //case BT_file:
+    default:
+                     yylineno = 1;
+                     break;
+  }
+  //Print("start body (%s) at line %d\n",BT_name[t],yylineno);
+  currentVoice->start_lineno = yylineno;
+  //printf("start buffer typ %d\n",t);
+  //Voice *p=currentVoice;
+  //Print("-----------------\ncurr:");
+  //do
+  //{
+  //Print("voice fn:%s\n",p->filename);
+  //p=p->prev;
+  //}
+  //while (p!=NULL);
+  //Print("----------------\n");
+}
+
+/*2
+* exit Buffer of type 'typ':
+* returns 1 if buffer type could not be found
+*/
+BOOLEAN exitBuffer(feBufferTypes typ)
+{
+  //printf("exitBuffer: %d(%s),(%x)\n",
+  //  typ,BT_name[typ], currentVoice);
+  //Voice *p=currentVoice;
+  //Print("-----------------\ncurr:");
+  //do
+  //{
+  //Print("voice fn:%s\n",p->filename);
+  //p=p->prev;
+  //}
+  //while (p!=NULL);
+  //Print("----------------\n");
+  if (typ == BT_break)  // valid inside for, while. may skip if, else
+  {
+    /*4 first check for valid buffer type, skip if/else*/
+    Voice *p=currentVoice;
+    loop
+    {
+      if ((p->typ != BT_if)
+      &&(p->typ != BT_else))
+      {
+        if (p->typ == BT_break /*typ*/)
+        {
+          while (p != currentVoice)
+          {
+            exitVoice();
+          }
+          exitVoice();
+          return FALSE;
+        }
+        else return TRUE;
+      }
+      if (p->prev==NULL) break;
+      p=p->prev;
+    }
+    /*4 break not inside a for/while: return an error*/
+    if (/*typ*/ BT_break != currentVoice->typ) return 1;
+    return exitVoice();
+  }
+
+  if ((typ == BT_proc)
+  || (typ == BT_example))
+  {
+    Voice *p=currentVoice;
+    loop
+    {
+      if ((p->typ == BT_proc)
+      || (p->typ == BT_example))
+      {
+        while (p != currentVoice)
+        {
+          exitVoice();
+        }
+        exitVoice();
+        return FALSE;
+      }
+      if (p->prev==NULL) break;
+      p=p->prev;
+    }
+  }
+  /*4 return not inside a proc: return an error*/
+  return TRUE;
+}
+
+/*2
+* jump to the beginning of a buffer
+*/
+BOOLEAN contBuffer(feBufferTypes typ)
+{
+  //printf("contBuffer: %d(%s),(%x)\n",
+  //  typ,BT_name[typ], currentVoice);
+  if (typ == BT_break)  // valid inside for, while. may skip if, else
+  {
+    // first check for valid buffer type
+    Voice *p=currentVoice;
+    loop
+    {
+      if ((p->typ != BT_if)
+        &&(p->typ != BT_else))
+      {
+        if (p->typ == BT_break /*typ*/)
+        {
+          while (p != currentVoice)
+          {
+            exitVoice();
+          }
+          yylineno = currentVoice->start_lineno;
+          currentVoice->fptr=0;
+          return FALSE;
+        }
+        else return TRUE;
+      }
+      if (p->prev==NULL) break;
+      p=p->prev;
+    }
+  }
+  return TRUE;
+}
+
+/*2
+* leave a voice: kill local variables
+* setup everything from the previous level
+* return 1 if leaving the top level, 0 otherwise
+*/
+BOOLEAN exitVoice()
+{
+  //printf("exitVoice: %d(%s),(%x)\n",
+  //  currentVoice->typ,BT_name[currentVoice->typ], currentVoice);
+  //{
+  //Voice *p=currentVoice;
+  //Print("-----------------\ncurr:");
+  //do
+  //{
+  //Print("voice fn:%s\n",p->filename);
+  //p=p->prev;
+  //}
+  //while (p!=NULL);
+  //Print("----------------\n");
+  //}
+  if (currentVoice!=NULL)
+  {
+    if (currentVoice->oldb!=NULL)
+    {
+      myyoldbuffer(currentVoice->oldb);
+      currentVoice->oldb=NULL;
+    }
+    if ((currentVoice->prev==NULL)&&(currentVoice->sw==BI_file))
+    {
+      currentVoice->prev=feInitStdin(currentVoice);
+    }
+    if (currentVoice->prev!=NULL)
+    {
+      //printf("exitVoice typ %d(%s)\n",
+      //  currentVoice->typ,BT_name[currentVoice->typ]);
+      if (currentVoice->typ==BT_if)
+      {
+        currentVoice->prev->ifsw=2;
+      }
+      else
+      {
+        currentVoice->prev->ifsw=0;
+      }
+      if ((currentVoice->sw == BI_file)
+      && (currentVoice->files!=NULL))
+      {
+        fclose(currentVoice->files);
+      }
+      if (currentVoice->filename!=NULL)
+      {
+        omFree((ADDRESS)currentVoice->filename);
+        currentVoice->filename=NULL;
+      }
+      if (currentVoice->buffer!=NULL)
+      {
+        omFree((ADDRESS)currentVoice->buffer);
+        currentVoice->buffer=NULL;
+      }
+      yylineno=currentVoice->prev->curr_lineno;
+      currentVoice->prev->next=NULL;
+    }
+    Voice *p=currentVoice->prev;
+    delete currentVoice;
+    currentVoice=p;
+  }
+  return currentVoice==NULL;
+}
+
+/*2
+* set prompt_char
+* only called with currentVoice->sw == BI_stdin
+*/
+static void feShowPrompt(void)
+{
+  fe_promptstr[0]=prompt_char;
+#ifdef macintosh
+  cols = 0;
+  printf(fe_promptstr);mflush();
+#endif
+}
+
+/*2
+* print echo (si_echo or TRACE), set my_yylinebuf
+*/
+static int fePrintEcho(char *anf, char *b)
+{
+  char *ss=strrchr(anf,'\n');
+  int len_s;
+  if (ss==NULL)
+  {
+    len_s=strlen(anf);
+  }
+  else
+  {
+    len_s=ss-anf+1;
+  }
+  // my_yylinebuf:
+  int mrc=si_min(len_s,79)-1;
+  strcpy(my_yylinebuf,anf+(len_s-1)-mrc);
+  if (my_yylinebuf[mrc] == '\n') my_yylinebuf[mrc] = '\0';
+  mrc--;
+  // handle echo:
+  if (((si_echo>myynest)
+    && ((currentVoice->typ==BT_proc)
+      || (currentVoice->typ==BT_example)
+      || (currentVoice->typ==BT_file)
+      || (currentVoice->typ==BT_none)
+    )
+    && (strncmp(anf,";return();",10)!=0)
+   )
+  || (traceit&TRACE_SHOW_LINE)
+  || (traceit&TRACE_SHOW_LINE1))
+  {
+    if (currentVoice->typ!=BT_example)
+    {
+      if (currentVoice->filename==NULL)
+        Print("(none) %3d%c ",yylineno,prompt_char);
+      else
+        Print("%s %3d%c ",currentVoice->filename,yylineno,prompt_char);
+     }
+    #ifdef HAVE_TCL
+    if(tclmode)
+    {
+      PrintTCL('N',len_s,anf);
+    }
+    else
+    #endif
+    {
+      fwrite(anf,1,len_s,stdout);
+      mflush();
+    }
+    if (traceit&TRACE_SHOW_LINE)
+    {
+      #ifdef HAVE_TCL
+      if(!tclmode)
+      #endif
+      while(fgetc(stdin)!='\n');
+    }
+  }
+  else if (traceit&TRACE_SHOW_LINENO)
+  {
+    Print("{%d}",yylineno);
+    mflush();
+  }
+#ifdef HAVE_SDB
+  if ((blocknest==0)
+  && (currentVoice->pi!=NULL)
+  && (currentVoice->pi->trace_flag!=0))
+  {
+    sdb(currentVoice, anf, len_s);
+  }
+#endif
+  prompt_char = '.';
+  return len_s;
+}
+
+int feReadLine(char* b, int l)
+{
+  char *s=NULL;
+  int offset = 0; /* will not be used if s==NULL*/
+  // try to read from the buffer into b, max l chars
+  if (currentVoice!=NULL)
+  {
+    if((currentVoice->buffer!=NULL)
+    && (currentVoice->buffer[currentVoice->fptr]!='\0'))
+    {
+  NewBuff:
+      register int i=0;
+      long startfptr=currentVoice->fptr;
+      long tmp_ptr=currentVoice->fptr;
+      l--;
+      loop
+      {
+        register char c=
+        b[i]=currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/];
+        i++;
+        if (yy_noeof==noeof_block)
+        {
+          if (c<' ')  yylineno++;
+          else if (c=='}') break;
+        }
+        else
+        {
+          if ((c<' ') ||
+          (c==';') ||
+          (c==')')
+          )
+            break;
+        }
+        if (i>=l) break;
+        tmp_ptr++;/*currentVoice->fptr++;*/
+        if(currentVoice->buffer[tmp_ptr/*currentVoice->fptr*/]=='\0') break;
+      }
+      currentVoice->fptr=tmp_ptr;
+      b[i]='\0';
+      if (currentVoice->sw==BI_buffer)
+      {
+        if (startfptr==0)
+        {
+          char *anf=currentVoice->buffer;
+          char *ss=strchr(anf,'\n');
+          int len;
+          if (ss==NULL) len=strlen(anf);
+          else          len=ss-anf;
+          char *s=(char *)omAlloc(len+2);
+          strncpy(s,anf,len+2);
+          s[len+1]='\0';
+          fePrintEcho(s,b);
+          omFree((ADDRESS)s);
+        }
+        else if (/*(startfptr>0) &&*/
+        (currentVoice->buffer[startfptr-1]=='\n'))
+        {
+          char *anf=currentVoice->buffer+startfptr;
+          char *ss=strchr(anf,'\n');
+          int len;
+          if (ss==NULL) len=strlen(anf);
+          else          len=ss-anf;
+          char *s=(char *)omAlloc(len+2);
+          strncpy(s,anf,len+2);
+          s[len+1]='\0';
+          yylineno++;
+          fePrintEcho(s,b);
+          omFree((ADDRESS)s);
+        }
+      }
+      currentVoice->fptr++;
+      return i;
+    }
+    // no buffer there or e-o-buffer or eoln:
+    if (currentVoice->sw!=BI_buffer)
+    {
+      currentVoice->fptr=0;
+      if (currentVoice->buffer==NULL)
+      {
+        currentVoice->buffer=(char *)omAlloc(4096-sizeof(ADDRESS));
+        omMarkAsStaticAddr(currentVoice->buffer);
+      }
+    }
+    offset=0;
+  NewRead:
+    yylineno++;
+    if (currentVoice->sw==BI_stdin)
+    {
+      feShowPrompt();
+      s=fe_fgets_stdin(fe_promptstr,
+                       &(currentVoice->buffer[offset]),
+                       (4096-1-sizeof(ADDRESS))-offset);
+      int i=0;
+      if (s!=NULL)
+        while((s[i]!='\0') && (i<4096)) {s[i] &= (char)127;i++;}
+    }
+    else if (currentVoice->sw==BI_file)
+    {
+      s=fgets(currentVoice->buffer+offset,(4096-1-sizeof(ADDRESS))-offset,
+              currentVoice->files);
+    }
+    //else /* BI_buffer */ s==NULL  => return 0
+    // done by the default return
+  }
+  if (s!=NULL)
+  {
+    // handle prot:
+    if (feProt&PROT_I)
+    {
+      fputs(s,feProtFile);
+    }
+    int rc=fePrintEcho(s,b)+1;
+    //s[strlen(s)+1]='\0'; add an second \0 at the end of the string
+    s[rc]='\0';
+    // handel \\ :
+    rc-=3;
+    if ((s[rc]=='\\')&&(currentVoice->sw!=BI_buffer))
+    {
+      s[rc]='\0';
+      offset+=rc;
+      if (offset<(int)omSizeOfAddr(currentVoice->buffer)) goto NewRead;
+    }
+    goto NewBuff;
+  }
+  /* else if (s==NULL) */
+  {
+    char *err;
+    switch(yy_noeof)
+    {
+      case noeof_brace:
+      case noeof_block:
+        err="{...}";
+        break;
+      case noeof_asstring:
+        err="till `.`";
+        break;
+      case noeof_string:
+        err="string";
+        break;
+      case noeof_bracket:
+        err="(...)";
+        break;
+      case noeof_procname:
+        err="proc";
+        break;
+      case noeof_comment:
+        err="/*...*/";
+        break;
+      default:
+        return 0;
+    }
+    Werror("premature end of file while reading %s",err);
+    return 0;
+  }
+}
+
+#ifdef __MWERKS__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef macintosh
+int    isatty(int filedes);
+#else
+int    _isatty(int filedes);
+#define isatty  _isatty
+#endif /* macintosh */
+#ifdef __cplusplus
+}
+#endif
+#endif
+/*2
+* init all data structures
+*/
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+Voice * feInitStdin(Voice *pp)
+{
+  Voice *p = new Voice;
+  p->files = stdin;
+  #ifdef HAVE_TCL
+  p->sw = (tclmode || isatty(STDIN_FILENO)) ? BI_stdin : BI_file;
+  #else
+  p->sw = (isatty(STDIN_FILENO)) ? BI_stdin : BI_file;
+  #endif
+  if ((pp!=NULL) && (pp->files==stdin))
+  {
+    p->files=freopen("/dev/tty","r",stdin);
+    //stdin=p->files;
+    p->sw = BI_stdin;
+  }
+  p->filename   = omStrDup("STDIN");
+  p->start_lineno   = 1;
+  omMarkAsStaticAddr(p);
+  omMarkAsStaticAddr(p->filename);
+  return p;
+}
+/*****************************************************************
+ *
+ * File handling
+ *
+ *****************************************************************/
+
+FILE * feFopen(char *path, char *mode, char *where,int useWerror,
+               int path_only)
+{
+  char longpath[MAXPATHLEN];
+  if (path[0]=='~')
+  {
+    if (path[1] == DIR_SEP)
+    {
+      char* home = getenv("HOME");
+#ifdef ix86_Win
+      if ((home==NULL)||(!access(home,X_OK)))
+        home = getenv("SINGHOME");
+#endif
+      if (home != NULL)
+      {
+        strcpy(longpath, home);
+        strcat(longpath, &(path[1]));
+        path = longpath;
+      }
+    }
+#if defined(HAVE_PWD_H) && defined(HAVE_GETPWNAM)
+    else
+    {
+      char* dir_sep;
+      struct passwd *pw_entry;
+      strcpy (longpath, path);
+      dir_sep = strchr(longpath, DIR_SEP);
+      *dir_sep = '\0';
+      pw_entry = getpwnam(&longpath[1]);
+      if (pw_entry != NULL)
+      {
+        strcpy(longpath, pw_entry->pw_dir);
+        dir_sep = strchr(path, DIR_SEP);
+        strcat(longpath, dir_sep);
+        path = longpath;
+      }
+    }
+#endif
+  }
+  FILE * f=NULL;
+  if (! path_only)
+  {
+    struct stat statbuf;
+    if ((stat(path,&statbuf)==0)
+    && (S_ISREG(statbuf.st_mode)))
+      f = myfopen(path,mode);
+  }
+  if (where!=NULL) strcpy(where,path);
+  if ((*mode=='r') &&
+      (path[0]!=DIR_SEP) &&
+      ! (path[0] == '.' && path[1] == DIR_SEP) &&
+      (f==NULL))
+  {
+    char found = 0;
+    char* spath = feResource('s');
+    char *s;
+
+    if (where==NULL) s=(char *)omAlloc(250);
+    else             s=where;
+
+    if (spath!=NULL)
+    {
+      char *p,*q;
+      p = spath;
+      while( (q=strchr(p, fePathSep)) != NULL)
+      {
+        *q = '\0';
+        strcpy(s,p);
+        *q = fePathSep;
+        strcat(s, DIR_SEPP);
+        strcat(s, path);
+        #ifndef macintosh
+          if(!access(s, R_OK)) { found++; break; }
+        #else
+          f=fopen(s,mode); /* do not need myfopen: we test only the access */
+          if (f!=NULL)  { found++; fclose(f); break; }
+        #endif
+        p = q+1;
+      }
+      if(!found)
+      {
+        strcpy(s,p);
+        strcat(s, DIR_SEPP);
+        strcat(s, path);
+      }
+      f=myfopen(s,mode);
+      if (f!=NULL)
+      {
+        if (where==NULL) omFree((ADDRESS)s);
+        return f;
+      }
+    }
+    else
+    {
+      if (where!=NULL) strcpy(s/*where*/,path);
+      f=myfopen(path,mode);
+    }
+    if (where==NULL) omFree((ADDRESS)s);
+  }
+  if ((f==NULL)&&(useWerror))
+    Werror("cannot open `%s`",path);
+  return f;
+}
+
+static char * feBufferStart;
+  /* only used in StringSet(S)/StringAppend(S)*/
+char * StringAppend(char *fmt, ...)
+{
+  va_list ap;
+  char *s = feBufferStart; /*feBuffer + strlen(feBuffer);*/
+  int more, vs;
+  va_start(ap, fmt);
+  if ((more=feBufferStart-feBuffer+strlen(fmt)+100)>feBufferLength)
+  {
+    more = ((more + (4*1024-1))/(4*1024))*(4*1024);
+    int l=s-feBuffer;
+    feBuffer=(char *)omReallocSize((ADDRESS)feBuffer,feBufferLength,
+                                                     more);
+    omMarkAsStaticAddr(feBuffer);
+    feBufferLength=more;
+    s=feBuffer+l;
+#ifndef BSD_SPRINTF
+    feBufferStart=s;
+#endif
+  }
+#ifdef BSD_SPRINTF
+  vsprintf(s, fmt, ap);
+  while (*s!='\0') s++;
+  feBufferStart =s;
+#else
+#ifdef HAVE_VSNPRINTF
+  vs = vsnprintf(s, feBufferLength - (feBufferStart - feBuffer), fmt, ap);
+  if (vs == -1)
+  {
+    assume(0);
+    feBufferStart = feBuffer + feBufferLength -1;
+  }
+  else
+  {
+    feBufferStart += vs;
+  }
+#else
+  feBufferStart += vsprintf(s, fmt, ap);
+#endif
+#endif
+  omCheckAddrSize(feBuffer, feBufferLength);
+  va_end(ap);
+  return feBuffer;
+}
+
+char * StringAppendS(char *st)
+{
+  /* feBufferStart is feBuffer + strlen(feBuffer);*/
+  int more,l;
+  int ll=feBufferStart-feBuffer;
+  if ((more=ll+2+(l=strlen(st)))>feBufferLength)
+  {
+    more = ((more + (4*1024-1))/(4*1024))*(4*1024);
+    feBuffer=(char *)omReallocSize((ADDRESS)feBuffer,feBufferLength,
+                                                     more);
+    feBufferLength=more;
+    feBufferStart=feBuffer+ll;
+  }
+  strcat(feBufferStart, st);
+  feBufferStart +=l;
+  return feBuffer;
+}
+
+char * StringSetS(char *st)
+{
+  int more,l;
+  if ((l=strlen(st))>feBufferLength)
+  {
+    more = ((l + (4*1024-1))/(4*1024))*(4*1024);
+    feBuffer=(char *)omReallocSize((ADDRESS)feBuffer,feBufferLength,
+                                                     more);
+    feBufferLength=more;
+  }
+  strcpy(feBuffer,st);
+  feBufferStart=feBuffer+l;
+  return feBuffer;
+}
+
+#ifndef __MWERKS__
+#ifdef HAVE_TCL
+extern "C" {
+void PrintTCLS(const char c, const char *s)
+{
+  int l=strlen(s);
+  if (l>0) PrintTCL(c,l,s);
+}
+}
+#endif
+#endif
+
+extern "C" {
+void WerrorS(const char *s)
+{
+#ifdef HAVE_MPSR
+  if (fe_fgets_stdin==fe_fgets_dummy)
+  {
+    if (feErrors==NULL)
+    {
+      feErrors=(char *)omAlloc(256);
+      feErrorsLen=256;
+      *feErrors = '\0';
+    }
+    else
+    {
+      if (((int)(strlen((char *)s)+ 20 +strlen(feErrors)))>=feErrorsLen)
+      {
+        feErrors=(char *)omReallocSize(feErrors,feErrorsLen,feErrorsLen+256);
+        feErrorsLen+=256;
+      }
+    }
+    strcat(feErrors, "Singular error: ");
+    strcat(feErrors, (char *)s);
+  }
+  else
+#endif
+  {
+#ifdef HAVE_TCL
+    if (tclmode)
+    {
+      PrintTCLS('E',(char *)s);
+      PrintTCLS('E',"\n");
+    }
+    else
+#endif
+    {
+      fwrite("   ? ",1,5,stderr);
+      fwrite((char *)s,1,strlen((char *)s),stderr);
+      fwrite("\n",1,1,stderr);
+      fflush(stderr);
+      if (feProt&PROT_O)
+      {
+        fwrite("   ? ",1,5,feProtFile);
+        fwrite((char *)s,1,strlen((char *)s),feProtFile);
+        fwrite("\n",1,1,feProtFile);
+      }
+    }
+  }
+  errorreported = TRUE;
+}
+
+void Werror(char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+  char *s=(char *)omAlloc(256);
+  vsprintf(s, fmt, ap);
+  WerrorS(s);
+  omFreeSize(s,256);
+  va_end(ap);
+}
+
+void WarnS(const char *s)
+{
+  #define warn_str "// ** "
+#ifdef HAVE_TCL
+  if (tclmode)
+  {
+    PrintTCLS('W',warn_str);
+    PrintTCLS('W',s);
+    PrintTCLS('W',"\n");
+  }
+  else
+#endif
+  if (feWarn) /* ignore warnings if option --no-warn was given */
+  {
+    fwrite(warn_str,1,6,stdout);
+    fwrite(s,1,strlen(s),stdout);
+    fwrite("\n",1,1,stdout);
+    fflush(stdout);
+    if (feProt&PROT_O)
+    {
+      fwrite(warn_str,1,6,feProtFile);
+      fwrite(s,1,strlen(s),feProtFile);
+      fwrite("\n",1,1,feProtFile);
+    }
+  }
+}
+} /* end extern "C" */
+
+void Warn(const char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+  char *s=(char *)omAlloc(256);
+  vsprintf(s, fmt, ap);
+  WarnS(s);
+  omFreeSize(s,256);
+  va_end(ap);
+}
+
+
+#ifdef macintosh
+static  int lines = 0;
+static  int cols = 0;
+
+void mwrite(uchar c)
+{
+  if (c == '\n')
+  {
+    cols = 0;
+    if (lines == pagelength)
+    {
+      lines = 0;
+      fputs("pause>\n",stderr);
+      uchar c = fgetc(stdin);
+    }
+    else
+    {
+      lines++;
+      fePutChar(c);
+    }
+  }
+  else
+  {
+    fePutChar(c);
+    cols++;
+    if (cols == colmax)
+    {
+      // cols = 0;   //will be done by mwrite('\n');
+      mwrite('\n');
+    }
+  }
+}
+#endif
+
+// some routines which redirect the output of print to a string
+static char* sprint = NULL;
+void SPrintStart()
+{
+  sprint = omStrDup("");
+}
+
+static void SPrintS(char* s)
+{
+  omCheckAddr(sprint);
+  if (s == NULL) return;
+  int ls = strlen(s);
+  if (ls == 0) return;
+
+  char* ns;
+  int l = strlen(sprint);
+  ns = (char*) omAlloc((l + ls + 1)*sizeof(char));
+  if (l > 0) strcpy(ns, sprint);
+
+  strcpy(&(ns[l]), s);
+  omFree(sprint);
+  sprint = ns;
+  omCheckAddr(sprint);
+}
+
+char* SPrintEnd()
+{
+  char* ns = sprint;
+  sprint = NULL;
+  omCheckAddr(ns);
+  return ns;
+}
+
+// Print routines
+extern "C" {
+void PrintS(char *s)
+{
+  if (sprint != NULL)
+  {
+    SPrintS(s);
+    return;
+  }
+
+  if (feOut) /* do not print when option --no-out was given */
+  {
+
+#ifdef macintosh
+    char c;
+    while ('\0' != (c = *s++))
+    {
+      mwrite(c);
+    }
+#else
+#ifdef HAVE_TCL
+    if (tclmode)
+    {
+      PrintTCLS('N',s);
+    }
+    else
+#endif
+    {
+      fwrite(s,1,strlen(s),stdout);
+      fflush(stdout);
+      if (feProt&PROT_O)
+      {
+        fwrite(s,1,strlen(s),feProtFile);
+      }
+    }
+#endif
+  }
+}
+
+void PrintLn()
+{
+  PrintS("\n");
+}
+
+void Print(char *fmt, ...)
+{
+  if (sprint != NULL)
+  {
+    int ls = strlen(fmt);
+    va_list ap;
+    va_start(ap, fmt);
+    omCheckAddr(sprint);
+    if (fmt != NULL && ls > 0)
+    {
+      char* ns;
+      int l = strlen(sprint);
+      ns = (char*) omAlloc(sizeof(char)*(ls + l + 256));
+      if (l > 0)  strcpy(ns, sprint);
+
+#ifdef HAVE_VSNPRINTF
+      l = vsnprintf(&(ns[l]), ls+255, fmt, ap);
+      assume(l != -1);
+#else
+      vsprintf(&(ns[l]), fmt, ap);
+#endif
+      omCheckAddr(ns);
+      omFree(sprint);
+      sprint = ns;
+    }
+    va_end(ap);
+    return;
+  }
+  if (feOut)
+  {
+    va_list ap;
+    va_start(ap, fmt);
+#ifdef HAVE_TCL
+    if(tclmode)
+#endif
+#if (defined(HAVE_TCL) || defined(macintosh))
+    {
+      char *s=(char *)omAlloc(strlen(fmt)+256);
+      vsprintf(s,fmt, ap);
+#ifdef HAVE_TCL
+      PrintTCLS('N',s);
+#endif
+#ifdef macintosh
+      char c;
+      while ('\0' != (c = *s++))
+      {
+        mwrite(c);
+      }
+      if (feProt&PROT_O)
+      {
+        vfprintf(feProtFile,fmt,ap);
+      }
+#endif
+    }
+#endif
+#if !defined(macintosh) || defined(HAVE_TCL)
+#ifdef HAVE_TCL
+    else
+#endif
+    {
+      vfprintf(stdout, fmt, ap);
+      fflush(stdout);
+      if (feProt&PROT_O)
+      {
+        vfprintf(feProtFile,fmt,ap);
+      }
+    }
+#endif
+    va_end(ap);
+  }
+}
+
+/* end extern "C" */
+}
+
+void monitor(char* s, int mode)
+{
+  if (feProt)
+  {
+    fclose(feProtFile);
+    feProt = 0;
+  }
+  if ((s!=NULL) && (*s!='\0'))
+  {
+    feProtFile = myfopen(s,"w");
+    if (feProtFile==NULL)
+    {
+      Werror("cannot open %s",s);
+      feProt=0;
+    }
+    else
+      feProt = (BOOLEAN)mode;
+  }
+}
+
+
+char* eati(char *s, int *i)
+{
+  int l=0;
+
+  if    (*s >= '0' && *s <= '9')
+  {
+    *i = 0;
+    while (*s >= '0' && *s <= '9')
+    {
+      *i *= 10;
+      *i += *s++ - '0';
+      l++;
+      if ((l>=MAX_INT_LEN)||((*i) <0))
+      {
+        s-=l;
+        Werror("`%s` greater than %d(max. integer representation)",
+                s,MAX_INT_VAL);
+        return s;
+      }
+    }
+  }
+  else *i = 1;
+  return s;
+}
+#else /* ! STANDALONE_PARSER */
+#include <stdio.h>
+
+#endif
+
+#ifdef ix86_Win
+// Make sure that mode contains binary option
+FILE* myfopen(char *path, char *mode)
+{
+  char mmode[4];
+  int i;
+  int done = 0;
+
+  for (i=0;;i++)
+  {
+    mmode[i] = mode[i];
+    if (mode[i] == '\0') break;
+    if (mode[i] == 'b') done = 1;
+  }
+
+  if (! done)
+  {
+    mmode[i] = 'b';
+    mmode[i+1] = '\0';
+  }
+  return fopen(path, mmode);
+}
+#endif
+// replace "\r\n" by " \n" and "\r" by "\n"
+
+size_t myfread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+  size_t got = fread(ptr, size, nmemb, stream) * size;
+  size_t i;
+
+  for (i=0; i<got; i++)
+  {
+    if ( ((char*) ptr)[i] == '\r')
+    {
+      if (i+1 < got && ((char*) ptr)[i+1] == '\n')
+        ((char*) ptr)[i] = ' ';
+      else
+        ((char*) ptr)[i] = '\n';
+    }
+  }
+  return got;
+}
Index: kernel/febase.h
===================================================================
--- kernel/febase.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/febase.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,335 @@
+#ifndef FEBASE_H
+#define FEBASE_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: febase.h,v 1.1.1.1 2003-10-06 12:15:52 Singular Exp $ */
+/*
+* ABSTRACT: basic i/o
+*/
+#include <stdio.h>
+#include <string.h>
+#include "structs.h"
+
+/* define DIR_SEPP, etc */
+#ifdef macintosh /* mac os 9 */
+#  define  DIR_SEP ':'
+#  define  DIR_SEPP ":"
+#  define  UP_DIR ""
+#else  /* unix , WINNT */
+#  define  DIR_SEP '/'
+#  define  DIR_SEPP "/"
+#  define  UP_DIR ".."
+#endif  /* macintosh */
+// this might still get reset by feInitResources
+extern char fePathSep;
+
+/* define MAXPATHLEN */
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+/* the are versions of limits.h with incorrect values (IRIX_6)
+* let's include our own */
+
+#include <mylimits.h>
+
+/* OSF/1 and AIX_4 are missing the header for setenv, but the proc exists */
+#if defined(__alpha) || defined(AIX_4)
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+  int setenv(const char *name, const char *value, int overwrite);
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+
+#ifdef HAVE_LIBREADLINE
+  #define HAVE_READLINE 1
+#endif
+
+#ifdef HAVE_DYN_RL
+  #undef HAVE_READLINE
+  #define HAVE_FEREAD 1
+#elif ! defined(HAVE_READLINE)
+#ifndef ix86_Win
+  #define HAVE_FEREAD 1
+#endif
+#endif
+#ifdef ix86_Linux
+  // FEREAD stuff does not work with glibc2
+  #undef HAVE_FEREAD
+#endif
+
+/*
+// These are our versions of fopen and fread They are very similar to
+// the usual fopen and fread, except that on reading, they always
+// convert "\r\n" into " \n" and "\r" into "\n".
+//
+// IMPORTANT: do only use myfopen and myfread when reading text,
+// do never use fopen and fread
+*/
+#ifdef ix86_Win
+FILE *myfopen(char *path, char *mode);
+#else
+#define myfopen fopen
+#endif
+size_t myfread(void *ptr, size_t size, size_t nmemb, FILE *stream);
+
+
+extern char*  feErrors;
+extern char*  feArgv0;
+extern int    feErrorsLen;
+extern FILE*  feProtFile;
+extern FILE*  feFilePending; /*temp. storage for grammar.y */
+extern char   fe_promptstr[];
+extern int    si_echo, printlevel;
+extern int    pagelength, colmax;
+extern int    yy_blocklineno;
+extern int    yy_noeof;
+extern char   prompt_char;
+extern const char feNotImplemented[];
+#ifdef HAVE_TCL
+extern BOOLEAN tclmode;
+#endif
+extern BOOLEAN errorreported;
+extern BOOLEAN feProt;
+extern BOOLEAN feWarn;
+extern BOOLEAN feOut;
+
+
+#define PROT_NONE 0
+#define PROT_I    1
+#define PROT_O    2
+#define PROT_IO   3
+
+/* the C-part: */
+#define mflush() fflush(stdout)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void    Werror(char *fmt, ...);
+void    WerrorS(const char *s);
+void    WarnS(const char *s);
+void    Print(char* fmt, ...);
+void    PrintLn();
+#ifdef HAVE_TCL
+void    PrintTCLS(const char c, const char * s);
+#else
+#define PrintTCLS(A,B) Print("TCL-ErrS:%s",B)
+#endif
+void    PrintS(char* s);
+char*   feGetResource(const char id);
+
+#ifdef HAVE_FEREAD
+extern BOOLEAN fe_is_raw_tty;
+void           fe_temp_reset (void);
+#endif
+
+#ifdef __cplusplus
+}
+/* the C++-part: */
+
+enum   feBufferTypes
+{
+  BT_none  = 0,  // entry level
+  BT_break = 1,  // while, for
+  BT_proc,       // proc
+  BT_example,    // example
+  BT_file,       // <"file"
+  BT_execute,    // execute
+  BT_if,         // if
+  BT_else        // else
+};
+
+enum   feBufferInputs
+{
+  BI_stdin = 1,
+  BI_buffer,
+  BI_file
+};
+
+/*****************************************************************
+ *
+ * Resource management (feResources.cc)
+ *
+ *****************************************************************/
+// returns value of Resource as read-only string, or NULL
+// if Resource not found
+// issues warning, if explicitely requested (warn > 0), or
+// if warn < 0 and Resource is gotten for the first time
+// Always quiet if warn == 0
+char* feResource(const char id, int warn = -1);
+char* feResource(const char* key, int warn = -1);
+// This needs to be called before the first call to feResource
+// Initializes Resources, SearchPath, and extends PATH
+void feInitResources(char* argv0);
+// Re-inits resources, should be called after changing env. variables
+void feReInitResources();
+// Prints resources into string with StringAppend, etc
+void feStringAppendResources(int warn = -1);
+
+/*****************************************************************
+ *
+ * help system (fehelp.cc)
+ *
+ *****************************************************************/
+// if str != NULL display help for str
+// display general help, otherwise
+void feHelp(char* str = NULL);
+// if browser != NULL or feOpt("browser") != NULL
+//    set HelpBrowser to browser
+// otherwise, if browser was already set, leave as is,
+//            if not, choose first available browser
+// return string identifying current browser
+// keeps feOpt("browser") up-to-date
+// Optional warn argument is as in feResource
+char* feHelpBrowser(char* browser = NULL, int warn = -1);
+void feStringAppendBrowsers(int warn = -1);
+
+/*****************************************************************
+ *
+ * version Id
+ *
+ *****************************************************************/
+/* extern unsigned long feVersionId; */
+
+/*****************************************************************
+ *
+ * File Stuff
+ *
+ *****************************************************************/
+FILE *  feFopen(char *path, char *mode, char *where=NULL, int useWerror=FALSE,
+                int path_only=FALSE);
+
+#ifndef __MWERKS__
+#ifdef HAVE_TCL
+
+inline void PrintTCL(const char c, int l,const char *s)
+{
+  if (s!=NULL) printf("%c:%d:%s",c,l,s);
+  else if(l==0) printf("%c:0:",c);
+  else printf("%c:1:%c",c,'0'+l);
+  fflush(stdout);
+}
+#else
+#define PrintTCL(A,B,C) Print("TCL-Err:%s",C)
+#endif /* HAVE_TCL */
+#endif /* __MWERKS__ */
+
+char *  StringAppend(char *fmt, ...);
+char *  StringAppendS(char *s);
+char *  StringSetS(char* s);
+const  char * VoiceName();
+void    VoiceBackTrack();
+void    Warn(const char *fmt, ...);
+BOOLEAN contBuffer(feBufferTypes typ);
+char *  eati(char *s, int *i);
+BOOLEAN exitBuffer(feBufferTypes typ);
+BOOLEAN exitVoice();
+void    monitor(char* s,int mode);
+BOOLEAN newFile(char* fname, FILE *f=NULL);
+void    newBuffer(char* s, feBufferTypes t, procinfo *pname = NULL, int start_lineno = 0);
+void *  myynewbuffer();
+void    myyoldbuffer(void * oldb);
+
+class Voice
+{
+  public:
+    Voice  * next;
+    Voice  * prev;
+    char   * filename;    // file name or proc name
+    procinfo * pi;        // proc info
+    void   * oldb;        // internal scanner buffer
+    // for files only:
+    FILE * files;         // file handle
+    // for buffers only:
+    char * buffer;        // buffer pointer
+    long   fptr;          // current position in buffer
+
+    int    start_lineno;  // lineno, to restore in recursion
+    int    curr_lineno;   // current lineno
+    feBufferInputs   sw;  // BI_stdin: read from STDIN
+                          // BI_buffer: buffer
+                          // BI_file: files
+    char   ifsw;          // if-switch:
+            /*1 ifsw==0: no if statement, else is invalid
+            *       ==1: if (0) processed, execute else
+            *       ==2: if (1) processed, else allowed but not executed
+            */
+    feBufferTypes   typ;  // buffer type: see BT_..
+
+  Voice() { memset(this,0,sizeof(*this));}
+  feBufferTypes Typ();
+  void Next();
+} ;
+
+extern Voice  *currentVoice;
+
+Voice * feInitStdin(Voice *pp);
+
+/* feread.cc: */
+
+/* the interface for reading: */
+extern  char * (*fe_fgets_stdin)(char *pr,char *s, int size);
+
+#ifdef HAVE_DYN_RL
+char * fe_fgets_stdin_drl(char *pr,char *s, int size);
+#endif
+
+extern "C" void fe_reset_input_mode();
+
+#ifndef MSDOS
+extern "C" {
+#ifndef HAVE_ATEXIT
+void fe_reset_fe (int i, void *v);
+#else
+void fe_reset_fe (void);
+#endif
+}
+#endif
+
+
+/* possible implementations: */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+  /* readline, linked in: */
+  char * fe_fgets_stdin_rl(char *pr,char *s, int size);
+
+  /* emulated readline: */
+  char * fe_fgets_stdin_emu(char *pr,char *s, int size);
+
+  /* fgets: */
+  char * fe_fgets(char *pr,char *s, int size);
+
+  #ifdef HAVE_TCL
+  /* tcl: */
+  char * fe_fgets_tcl(char *pr,char *s, int size);
+  #endif
+
+  /* dummy (for batch mode): */
+  char * fe_fgets_dummy(char *pr,char *s, int size);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* c++ only */
+
+/* everything in between calls to these procedures is printed into a string
+ * which is returned by SprintEnd()
+ */
+void SPrintStart();
+char* SPrintEnd();
+
+
+#endif /* ifndef FEBASE_H */
Index: kernel/fegetopt.c
===================================================================
--- kernel/fegetopt.c	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/fegetopt.c	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,751 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: fegetopt.c,v 1.1.1.1 2003-10-06 12:15:52 Singular Exp $ */
+
+/* Getopt for GNU.
+   NOTE: getopt is now part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
+   before changing it!
+
+   Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94
+        Free Software Foundation, Inc.
+
+   This program 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.
+
+   This program 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 this program; if not, write to the Free Software
+   Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* 
+   obachman 9/99: adapted to Singular by 
+    * adding prefix fe_ to global variables
+    * extended fe_option structure    
+*/
+
+
+#include "mod2.h"
+
+#ifndef __STDC__
+#  ifndef const
+#    define const
+#  endif
+#endif
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.  */
+#ifndef _NO_PROTO
+#define _NO_PROTO
+#endif
+
+#include <stdio.h>
+/* #include "tailor.h" */
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef  __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+   contain conflicting prototypes for getopt.  */
+#include <stdlib.h>
+#endif  /* GNU C library.  */
+
+/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
+   long-named option.  Because this is not POSIX.2 compliant, it is
+   being phased out.  */
+/* #define GETOPT_COMPAT */
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+   but it behaves differently for the user, since it allows the user
+   to intersperse the options with the other arguments.
+
+   As `getopt' works, it permutes the elements of ARGV so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Setting the environment variable POSIXLY_CORRECT disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#include "fegetopt.h"
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+char *fe_optarg = 0;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `fe_optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+/* XXX 1003.2 says this must be 1 before any call.  */
+int fe_optind = 0;
+
+/* The next char to be scanned in the option-element
+   in which the last option character we returned was found.
+   This allows us to pick up the scan where we left off.
+
+   If this is zero, or a null string, it means resume the scan
+   by advancing to the next ARGV-element.  */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int fe_opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+#define BAD_OPTION '\0'
+int fe_optopt = BAD_OPTION;
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   The special argument `--' forces an end of option-scanning regardless
+   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return EOF with `fe_optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+#ifdef  __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+   because there are many ways it can cause trouble.
+   On some systems, it contains special magic macros that don't work
+   in GCC.  */
+#include <string.h>
+#define my_index        strchr
+#define my_strlen       strlen
+#else
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+#if __STDC__ || defined(PROTO)
+extern char *getenv(const char *name);
+extern int  strcmp (const char *s1, const char *s2);
+/*extern int  strncmp(const char *s1, const char *s2, int n);*/
+
+static int my_strlen(const char *s);
+static char *my_index (const char *str, int chr);
+#else
+extern char *getenv ();
+#endif
+
+static int my_strlen (const char *str)
+{
+  int n = 0;
+  while (*str++)
+    n++;
+  return n;
+}
+
+static char * my_index (const char *str, int chr)
+{
+  while (*str)
+    {
+      if (*str == chr)
+        return (char *) str;
+      str++;
+    }
+  return 0;
+}
+
+#endif                          /* GNU C library.  */
+
+/* Handle permutation of arguments.  */
+
+/* Describe the part of ARGV that contains non-options that have
+   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+   `last_nonopt' is the index after the last of them.  */
+
+static int first_nonopt;
+static int last_nonopt;
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,fe_optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.
+
+   To perform the swap, we first reverse the order of all elements. So
+   all options now come before all non options, but they are in the
+   wrong order. So we put back the options and non options in original
+   order by reversing them again. For example:
+       original input:      a b c -x -y
+       reverse all:         -y -x c b a
+       reverse options:     -x -y c b a
+       reverse non options: -x -y a b c
+*/
+
+#if __STDC__ || defined(PROTO)
+static void exchange (char **argv);
+#endif
+
+static void exchange (char **argv)
+{
+  char *temp, **first, **last;
+
+  /* Reverse all the elements [first_nonopt, fe_optind) */
+  first = &argv[first_nonopt];
+  last  = &argv[fe_optind-1];
+  while (first < last) {
+    temp = *first; *first = *last; *last = temp; first++; last--;
+  }
+  /* Put back the options in order */
+  first = &argv[first_nonopt];
+  first_nonopt += (fe_optind - last_nonopt);
+  last  = &argv[first_nonopt - 1];
+  while (first < last) {
+    temp = *first; *first = *last; *last = temp; first++; last--;
+  }
+
+  /* Put back the non options in order */
+  first = &argv[first_nonopt];
+  last_nonopt = fe_optind;
+  last  = &argv[last_nonopt-1];
+  while (first < last) {
+    temp = *first; *first = *last; *last = temp; first++; last--;
+  }
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `fe_optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns `EOF'.
+   Then `fe_optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return BAD_OPTION after printing an error message.  If you set `fe_opterr' to
+   zero, the error message is suppressed but we still return BAD_OPTION.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `fe_optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `fe_optarg', otherwise `fe_optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns
+   the value of the option's `val' field.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct fe_option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int _fe_getopt_internal (
+     int argc,
+     char *const *argv,
+     const char *optstring,
+     const struct fe_option *longopts,
+     int *longind,
+     int long_only)
+{
+  int option_index;
+
+  fe_optarg = 0;
+
+  /* Initialize the internal data when the first call is made.
+     Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  if (fe_optind == 0)
+    {
+      first_nonopt = last_nonopt = fe_optind = 1;
+
+      nextchar = NULL;
+
+      /* Determine how to handle the ordering of options and nonoptions.  */
+
+      if (optstring[0] == '-')
+        {
+          ordering = RETURN_IN_ORDER;
+          ++optstring;
+        }
+      else if (optstring[0] == '+')
+        {
+          ordering = REQUIRE_ORDER;
+          ++optstring;
+        }
+      else if (getenv ("POSIXLY_CORRECT") != NULL)
+        ordering = REQUIRE_ORDER;
+      else
+        ordering = PERMUTE;
+    }
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      if (ordering == PERMUTE)
+        {
+          /* If we have just processed some options following some non-options,
+             exchange them so that the options come first.  */
+
+          if (first_nonopt != last_nonopt && last_nonopt != fe_optind)
+            exchange ((char **) argv);
+          else if (last_nonopt != fe_optind)
+            first_nonopt = fe_optind;
+
+          /* Now skip any additional non-options
+             and extend the range of non-options previously skipped.  */
+
+          while (fe_optind < argc
+                 && (argv[fe_optind][0] != '-' || argv[fe_optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+                 && (longopts == NULL
+                     || argv[fe_optind][0] != '+' || argv[fe_optind][1] == '\0')
+#endif                          /* GETOPT_COMPAT */
+                 )
+            fe_optind++;
+          last_nonopt = fe_optind;
+        }
+
+      /* Special ARGV-element `--' means premature end of options.
+         Skip it like a null option,
+         then exchange with previous non-options as if it were an option,
+         then skip everything else like a non-option.  */
+
+      if (fe_optind != argc && !strcmp (argv[fe_optind], "--"))
+        {
+          fe_optind++;
+
+          if (first_nonopt != last_nonopt && last_nonopt != fe_optind)
+            exchange ((char **) argv);
+          else if (first_nonopt == last_nonopt)
+            first_nonopt = fe_optind;
+          last_nonopt = argc;
+
+          fe_optind = argc;
+        }
+
+      /* If we have done all the ARGV-elements, stop the scan
+         and back over any non-options that we skipped and permuted.  */
+
+      if (fe_optind == argc)
+        {
+          /* Set the next-arg-index to point at the non-options
+             that we previously skipped, so the caller will digest them.  */
+          if (first_nonopt != last_nonopt)
+            fe_optind = first_nonopt;
+          return EOF;
+        }
+
+      /* If we have come to a non-option and did not permute it,
+         either stop the scan or describe it to the caller and pass it by.  */
+
+      if ((argv[fe_optind][0] != '-' || argv[fe_optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+          && (longopts == NULL
+              || argv[fe_optind][0] != '+' || argv[fe_optind][1] == '\0')
+#endif                          /* GETOPT_COMPAT */
+          )
+        {
+          if (ordering == REQUIRE_ORDER)
+            return EOF;
+          fe_optarg = argv[fe_optind++];
+          return 1;
+        }
+
+      /* We have found another option-ARGV-element.
+         Start decoding its characters.  */
+
+      nextchar = (argv[fe_optind] + 1
+                  + (longopts != NULL && argv[fe_optind][1] == '-'));
+    }
+
+  if (longopts != NULL
+      && ((argv[fe_optind][0] == '-'
+           && (argv[fe_optind][1] == '-' || long_only))
+#ifdef GETOPT_COMPAT
+          || argv[fe_optind][0] == '+'
+#endif                          /* GETOPT_COMPAT */
+          ))
+    {
+      const struct fe_option *p;
+      char *s = nextchar;
+      int exact = 0;
+      int ambig = 0;
+      const struct fe_option *pfound = NULL;
+      int indfound = 0;
+
+      while (*s && *s != '=')
+        s++;
+
+      /* Test all options for either exact match or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name;
+           p++, option_index++)
+        if (!strncmp (p->name, nextchar, s - nextchar))
+          {
+            if (s - nextchar == my_strlen (p->name))
+              {
+                /* Exact match found.  */
+                pfound = p;
+                indfound = option_index;
+                exact = 1;
+                break;
+              }
+            else if (pfound == NULL)
+              {
+                /* First nonexact match found.  */
+                pfound = p;
+                indfound = option_index;
+              }
+            else
+              /* Second nonexact match found.  */
+              ambig = 1;
+          }
+
+      if (ambig && !exact)
+        {
+          if (fe_opterr)
+            fprintf (stderr, "%s: option `%s' is ambiguous\n",
+                     argv[0], argv[fe_optind]);
+          nextchar += my_strlen (nextchar);
+          fe_optind++;
+          return BAD_OPTION;
+        }
+
+      if (pfound != NULL)
+        {
+          option_index = indfound;
+          fe_optind++;
+          if (*s)
+            {
+              /* Don't test has_arg with >, because some C compilers don't
+                 allow it to be used on enums.  */
+              if (pfound->has_arg)
+                fe_optarg = s + 1;
+              else
+                {
+                  if (fe_opterr)
+                    {
+                      if (argv[fe_optind - 1][1] == '-')
+                        /* --option */
+                        fprintf (stderr,
+                                 "%s: option `--%s' doesn't allow an argument\n",
+                                 argv[0], pfound->name);
+                      else
+                        /* +option or -option */
+                        fprintf (stderr,
+                             "%s: option `%c%s' doesn't allow an argument\n",
+                             argv[0], argv[fe_optind - 1][0], pfound->name);
+                    }
+                  nextchar += my_strlen (nextchar);
+                  return BAD_OPTION;
+                }
+            }
+          else if (pfound->has_arg == 1)
+            {
+              if (fe_optind < argc)
+                fe_optarg = argv[fe_optind++];
+              else
+                {
+                  if (fe_opterr)
+                    fprintf (stderr, "%s: option `%s' requires an argument\n",
+                             argv[0], argv[fe_optind - 1]);
+                  nextchar += my_strlen (nextchar);
+                  return optstring[0] == ':' ? ':' : BAD_OPTION;
+                }
+            }
+          nextchar += my_strlen (nextchar);
+          if (longind != NULL)
+            *longind = option_index;
+          return pfound->val;
+        }
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+         or the option starts with '--' or is not a valid short
+         option, then it's an error.
+         Otherwise interpret it as a short option.  */
+      if (!long_only || argv[fe_optind][1] == '-'
+#ifdef GETOPT_COMPAT
+          || argv[fe_optind][0] == '+'
+#endif                          /* GETOPT_COMPAT */
+          || my_index (optstring, *nextchar) == NULL)
+        {
+          if (fe_opterr)
+            {
+              if (argv[fe_optind][1] == '-')
+                /* --option */
+                fprintf (stderr, "%s: unrecognized option `--%s'\n",
+                         argv[0], nextchar);
+              else
+                /* +option or -option */
+                fprintf (stderr, "%s: unrecognized option `%c%s'\n",
+                         argv[0], argv[fe_optind][0], nextchar);
+            }
+          nextchar = (char *) "";
+          fe_optind++;
+          return BAD_OPTION;
+        }
+    }
+
+  /* Look at and handle the next option-character.  */
+
+  {
+    char c = *nextchar++;
+    char *temp = my_index (optstring, c);
+
+    /* Increment `fe_optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++fe_optind;
+
+    if (temp == NULL || c == ':')
+      {
+        if (fe_opterr)
+          {
+#if 0
+            if (c < 040 || c >= 0177)
+              fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
+                       argv[0], c);
+            else
+              fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
+#else
+            /* 1003.2 specifies the format of this message.  */
+            fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
+#endif
+          }
+        fe_optopt = c;
+        return BAD_OPTION;
+      }
+    if (temp[1] == ':')
+      {
+        if (temp[2] == ':')
+          {
+            /* This is an option that accepts an argument optionally.  */
+            if (*nextchar != '\0')
+              {
+                fe_optarg = nextchar;
+                fe_optind++;
+              }
+            else
+              fe_optarg = 0;
+            nextchar = NULL;
+          }
+        else
+          {
+            /* This is an option that requires an argument.  */
+            if (*nextchar != '\0')
+              {
+                fe_optarg = nextchar;
+                /* If we end this ARGV-element by taking the rest as an arg,
+                   we must advance to the next element now.  */
+                fe_optind++;
+              }
+            else if (fe_optind == argc)
+              {
+                if (fe_opterr)
+                  {
+#if 0
+                    fprintf (stderr, "%s: option `-%c' requires an argument\n",
+                             argv[0], c);
+#else
+                    /* 1003.2 specifies the format of this message.  */
+                    fprintf (stderr, "%s: option requires an argument -- %c\n",
+                             argv[0], c);
+#endif
+                  }
+                fe_optopt = c;
+                if (optstring[0] == ':')
+                  c = ':';
+                else
+                  c = BAD_OPTION;
+              }
+            else
+              /* We already incremented `fe_optind' once;
+                 increment it again when taking next ARGV-elt as argument.  */
+              fe_optarg = argv[fe_optind++];
+            nextchar = NULL;
+          }
+      }
+    return c;
+  }
+}
+
+int fe_getopt (
+     int argc,
+     char *const *argv,
+     const char *optstring)
+{
+  return _fe_getopt_internal (argc, argv, optstring,
+                           (const struct fe_option *) 0,
+                           (int *) 0,
+                           0);
+}
+
+int fe_getopt_long (
+     int argc,
+     char *const *argv,
+     const char *options,
+     const struct fe_option *long_options,
+     int *opt_index)
+{
+  return _fe_getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+int fe_getopt_long_only (
+     int argc,
+     char *const *argv,
+     const char *options,
+     const struct fe_option *long_options,
+     int *opt_index)
+{
+  return _fe_getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+#ifdef TEST_GETOPT
+
+/* Compile with -DTEST_GETOPT to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int main (int argc, char **argv)
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = fe_getopt (argc, argv, "abc:d:0123456789");
+      if (c == EOF)
+        break;
+
+      switch (c)
+        {
+        case '0':
+        case '1':
+        case '2':
+        case '3':
+        case '4':
+        case '5':
+        case '6':
+        case '7':
+        case '8':
+        case '9':
+          if (digit_optind != 0 && digit_optind != this_option_optind)
+            printf ("digits occur in two different argv-elements.\n");
+          digit_optind = this_option_optind;
+          printf ("option %c\n", c);
+          break;
+
+        case 'a':
+          printf ("option a\n");
+          break;
+
+        case 'b':
+          printf ("option b\n");
+          break;
+
+        case 'c':
+          printf ("option c with value `%s'\n", fe_optarg);
+          break;
+
+        case BAD_OPTION:
+          break;
+
+        default:
+          printf ("?? fe_getopt returned character code 0%o ??\n", c);
+        }
+    }
+
+  if (fe_optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (fe_optind < argc)
+        printf ("%s ", argv[fe_optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST_GETOPT */
Index: kernel/fegetopt.h
===================================================================
--- kernel/fegetopt.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/fegetopt.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,133 @@
+/* Declarations for getopt.
+   Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+
+   This program 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.
+
+   This program 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 this program; if not, write to the Free Software
+   Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+/*
+   obachman 9/99: adapted to Singular by
+    * adding prefix fe_ to global variables
+    * extended fe_option structure
+*/
+
+#ifndef FEGETOPT_H
+#define FEGETOPT_H 1
+
+#ifdef        __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *fe_optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int fe_optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int fe_opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int fe_optopt;
+
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument                (or 0) if the option does not take an argument,
+   required_argument        (or 1) if the option requires an argument,
+   optional_argument         (or 2) if the option takes an optional argument.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   `val' field to a nonzero value (the equivalent single-letter option
+   character, if there is one).
+   For long options `getopt' returns the contents of the `val' field.  */
+
+typedef enum {feOptUntyped, feOptBool, feOptInt, feOptString} feOptType;
+struct fe_option
+{
+#if        __STDC__
+  const char *name;
+#else
+  char *name;
+#endif
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int val;
+  /* Stuff added for Singular  */
+  const char*   arg_name;// name of argument, for display in help
+  const char*   help;    // (short) help string
+  feOptType     type;    // type of argument, if has_arg > 0
+  void*         value;   // (default) value of option
+  int           set;     // only relevant for strings: 0 if not set, 1 if set
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+#define        no_argument       0
+#define required_argument        1
+#define optional_argument        2
+
+#if __STDC__ || defined(PROTO) || defined(__MWERKS__)
+/* #if defined(__GNU_LIBRARY__)*/
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in stdlib.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern int fe_getopt (int argc, char *const *argv, const char *shortopts);
+/* #endif */
+extern int fe_getopt_long (int argc, char *const *argv, const char *shortopts,
+                        const struct fe_option *longopts, int *longind);
+extern int fe_getopt_long_only (int argc, char *const *argv,
+                             const char *shortopts,
+                             const struct fe_option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _fe_getopt_internal (int argc, char *const *argv,
+                             const char *shortopts,
+                             const struct fe_option *longopts, int *longind,
+                             int long_only);
+#else /* not __STDC__ */
+extern int fe_getopt ();
+extern int fe_getopt_long ();
+extern int fe_getopt_long_only ();
+
+extern int _fe_getopt_internal ();
+#endif /* not __STDC__ */
+
+#ifdef        __cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
Index: kernel/fehelp.cc
===================================================================
--- kernel/fehelp.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/fehelp.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1021 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT: help system
+*/
+
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "mod2.h"
+#include <mylimits.h>
+#include "omalloc.h"
+#include "febase.h"
+#include "feOpt.h"
+#include "dError.h"
+
+BOOLEAN heOnlineHelp(char* s); // -> ipshell.cc
+long heKeyChksum(char* key);   // -> ipshell.cc
+/*****************************************************************
+ *
+ * Declarations: Data  structures
+ *
+ *****************************************************************/
+#define MAX_HE_ENTRY_LENGTH 60
+typedef struct
+{
+  char key[MAX_HE_ENTRY_LENGTH];
+  char node[MAX_HE_ENTRY_LENGTH];
+  char url[MAX_HE_ENTRY_LENGTH];
+  long  chksum;
+} heEntry_s;
+typedef  heEntry_s * heEntry;
+
+typedef void (*heBrowserHelpProc)(heEntry hentry, int br);
+typedef BOOLEAN (*heBrowserInitProc)(int warn, int br);
+
+typedef struct
+{
+  char* browser;
+  heBrowserInitProc init_proc;
+  heBrowserHelpProc help_proc;
+  char* required;
+  char* action;
+} heBrowser_s;
+typedef heBrowser_s * heBrowser;
+
+/*****************************************************************
+ *
+ * Declarations: Local functions
+ *
+ *****************************************************************/
+static char* strclean(char* str);
+static BOOLEAN heKey2Entry(char* filename, char* key, heEntry hentry);
+static int heReKey2Entry (char* filename, char* key, heEntry hentry);
+static BOOLEAN strmatch(char* s, char* re);
+static void heBrowserHelp(heEntry hentry);
+
+// browser functions
+static BOOLEAN heGenInit(int,int);    static void heGenHelp(heEntry hentry,int);
+                                      static void heBuiltinHelp(heEntry hentry,int);
+static BOOLEAN heDummyInit(int,int);   static void heDummyHelp(heEntry hentry,int);
+static BOOLEAN heEmacsInit(int,int);   static void heEmacsHelp(heEntry hentry,int);
+
+#ifdef ix86_Win
+static void heHtmlHelp(heEntry hentry,int);
+static void heWinHelp(heEntry hentry,int);
+#include "sing_win.h"
+#endif
+
+static heBrowser heCurrentHelpBrowser = NULL;
+static int heCurrentHelpBrowserIndex= -1;
+
+
+/*****************************************************************
+ *
+ * Definition: available help browsers
+ *
+ *****************************************************************/
+// order is improtant -- first possible help is choosen
+#if 1
+static heBrowser_s *heHelpBrowsers=NULL;
+#else
+static heBrowser_s heHelpBrowsers[] =
+{
+#ifdef ix86_Win
+//  { "html",     heDummyInit,    heHtmlHelp, NULL, NULL},
+//  { "winhlp",   heDummyInit,    heWinHelp, NULL, NULL},
+#endif
+  { "mozilla",  heGenInit,      heGenHelp, "xDhE:mozilla:", "(mozilla -remote \"openURL(%h)\")||(mozilla %h)"},
+  { "netscape", heGenInit,      heGenHelp, "xDhE:netscape:", "(netscape -remote \"openURL(%h)\")||(netscape %h)"},
+  { "tkinfo",   heGenInit,      heGenHelp, "xDiE:tkinfo:", "tkinfo '(%i)%n' &"},
+  { "xinfo",    heGenInit,      heGenHelp, "xDiE:xterm:E:info:", "xterm -e info -f %i --node='%n' &"},
+  { "mac",      heGenInit,      heGenHelp,  "xhE:open:","open %h" },
+  { "machtml",  heGenInit,      heGenHelp,  "xE:open:","open %H" },
+  { "info",     heGenInit,      heGenHelp, "xiE:info:", "info -f %i --node='%n' &"},
+  { "builtin",  heGenInit,      heBuiltinHelp, "i", NULL},
+  { "dummy",    heDummyInit,    heDummyHelp, NULL, NULL},
+  { "emacs",    heEmacsInit,    heEmacsHelp, NULL, NULL},
+  { NULL, NULL, NULL, NULL, NULL} // must be the last record
+};
+#endif
+
+/*****************************************************************
+ *
+ * Implementation: public function
+ *
+ *****************************************************************/
+void feHelp(char *str)
+{
+  str = strclean(str);
+  if (str == NULL) {heBrowserHelp(NULL); return;}
+
+  if (strlen(str) > MAX_HE_ENTRY_LENGTH - 2)  // need room for extra **
+    str[MAX_HE_ENTRY_LENGTH - 3] = '\0';
+
+  BOOLEAN key_is_regexp = (strchr(str, '*') != NULL);
+  heEntry_s hentry;
+  char* idxfile = feResource('x' /*"IdxFile"*/);
+
+  // Try exact match of help string with key in index
+  if (!key_is_regexp && idxfile != NULL && heKey2Entry(idxfile, str, &hentry))
+  {
+    heBrowserHelp(&hentry);
+    return;
+  }
+
+  // try proc help and library help
+  if (! key_is_regexp && heOnlineHelp(str)) return;
+
+  // Try to match approximately with key in index file
+  if (idxfile != NULL)
+  {
+    char* matches = StringSetS("");
+    int found = heReKey2Entry(idxfile, str, &hentry);
+
+    // Try to match with str*
+    if (found == 0)
+    {
+      char mkey[MAX_HE_ENTRY_LENGTH];
+      strcpy(mkey, str);
+      strcat(mkey, "*");
+      found = heReKey2Entry(idxfile, mkey, &hentry);
+      // Try to match with *str*
+      if (found == 0)
+      {
+        mkey[0] = '*';
+        strcpy(mkey + 1, str);
+        strcat(mkey, "*");
+        found = heReKey2Entry(idxfile, mkey, &hentry);
+      }
+
+      // Print warning and return if nothing found
+      if (found == 0)
+      {
+        Warn("No help for topic '%s' (not even for '*%s*')", str, str);
+        WarnS("Try '?;'       for general help");
+        WarnS("or  '?Index;'  for all available help topics.");
+        return;
+      }
+    }
+
+    // do help if unique match was found
+    if (found == 1)
+    {
+      heBrowserHelp(&hentry);
+      return;
+    }
+    // Print warning about multiple matches and return
+    if (key_is_regexp)
+      Warn("No unique help for '%s'", str);
+    else
+      Warn("No help for topic '%s'", str);
+    Warn("Try one of");
+    PrintS(matches);
+    PrintS("\n");
+    return;
+  }
+
+  // no idx file, let Browsers deal with it, if they can
+  strcpy(hentry.key, str);
+  *hentry.node = '\0';
+  *hentry.url = '\0';
+  hentry.chksum = 0;
+  heBrowserHelp(&hentry);
+}
+static void feBrowserFile()
+{
+  FILE *f=feFopen("help.cnf","r",NULL,TRUE);
+  int br=0;
+  if (f!=NULL)
+  {
+    char buf[512];
+    while (fgets( buf, sizeof(buf), f))
+    {
+      if ((buf[0]!='#') && (buf[0]>' ')) br++;
+    }
+    fseek(f,0,SEEK_SET);
+    // for the 4(!) default browsers
+    heHelpBrowsers=(heBrowser_s*)omAlloc0((br+4)*sizeof(heBrowser_s));
+    br=0;
+    while (fgets( buf, sizeof(buf), f))
+    {
+      if ((buf[0]!='#') && (buf[0]>' '))
+      {
+        char *name=strtok(buf,"!");
+        char *req=strtok(NULL,"!");
+        char *cmd=strtok(NULL,"!");
+        while ((cmd[0]!='\0') && (cmd[strlen(cmd)-1]<=' '))
+          cmd[strlen(cmd)-1]='\0';
+        //Print("name %d >>%s<<\n\treq:>>%s<<\n\tcmd:>>%s<<\n",br,name,req,cmd);
+        heHelpBrowsers[br].browser=(char *)omStrDup(name);
+        heHelpBrowsers[br].init_proc=heGenInit;
+        heHelpBrowsers[br].help_proc=heGenHelp;
+        heHelpBrowsers[br].required=omStrDup(req);
+        heHelpBrowsers[br].action=omStrDup(cmd);
+        br++;
+      }
+    }
+    fclose(f);
+  }
+  else
+  {
+#ifdef ix86_Win
+    // for the 6(!) default browsers
+    heHelpBrowsers=(heBrowser_s*)omAlloc0(5*sizeof(heBrowser_s));
+#else
+    // for the 4(!) default browsers
+    heHelpBrowsers=(heBrowser_s*)omAlloc0(4*sizeof(heBrowser_s));
+#endif
+  }
+#ifdef ix86_Win
+  heHelpBrowsers[br].browser="winhlp";
+  heHelpBrowsers[br].init_proc=heGenInit;
+  heHelpBrowsers[br].help_proc=heWinHelp;
+  heHelpBrowsers[br].required="h";
+  //heHelpBrowsers[br].action=NULL;
+  br++;
+  heHelpBrowsers[br].browser="html";
+  heHelpBrowsers[br].init_proc=heGenInit;
+  heHelpBrowsers[br].help_proc=heHtmlHelp;
+  heHelpBrowsers[br].required="h";
+  //heHelpBrowsers[br].action=NULL;
+  br++;
+#endif
+  heHelpBrowsers[br].browser="builtin";
+  heHelpBrowsers[br].init_proc=heGenInit;
+  heHelpBrowsers[br].help_proc=heBuiltinHelp;
+  heHelpBrowsers[br].required="i";
+  //heHelpBrowsers[br].action=NULL;
+  br++;
+  heHelpBrowsers[br].browser="dummy";
+  heHelpBrowsers[br].init_proc=heDummyInit;
+  heHelpBrowsers[br].help_proc=heDummyHelp;
+  //heHelpBrowsers[br].required=NULL;
+  //heHelpBrowsers[br].action=NULL;
+  br++;
+  heHelpBrowsers[br].browser="emacs";
+  heHelpBrowsers[br].init_proc=heEmacsInit;
+  heHelpBrowsers[br].help_proc=heEmacsHelp;
+  //heHelpBrowsers[br].required=NULL;
+  //heHelpBrowsers[br].action=NULL;
+  //br++;
+  //heHelpBrowsers[br].browser=NULL;
+  //heHelpBrowsers[br].init_proc=NULL;
+  //heHelpBrowsers[br].help_proc=NULL;
+  //heHelpBrowsers[br].required=NULL;
+  //heHelpBrowsers[br].action=NULL;
+}
+
+char* feHelpBrowser(char* which, int warn)
+{
+  int i = 0;
+
+  // if no argument, choose first available help browser
+  if (heHelpBrowsers==NULL) feBrowserFile();
+  if (which == NULL || *which == '\0')
+  {
+    // return, if already set
+    if (heCurrentHelpBrowser != NULL)
+      return heCurrentHelpBrowser->browser;
+
+    // First, try emacs, if emacs-option is set
+    // Under Win, always use html
+#ifndef ix86_Win
+    if (feOptValue(FE_OPT_EMACS) != NULL)
+    {
+      while (heHelpBrowsers[i].browser != NULL)
+      {
+        if (strcmp(heHelpBrowsers[i].browser, "emacs") == 0 &&
+            (heHelpBrowsers[i].init_proc(0,i)))
+        {
+          heCurrentHelpBrowser = &(heHelpBrowsers[i]);
+          heCurrentHelpBrowserIndex=i;
+          goto Finish;
+        }
+        i++;
+      }
+      i=0;
+    }
+#endif
+    while (heHelpBrowsers[i].browser != NULL)
+    {
+      if (heHelpBrowsers[i].init_proc(0,i))
+      {
+        heCurrentHelpBrowser = &(heHelpBrowsers[i]);
+        heCurrentHelpBrowserIndex=i;
+        goto Finish;
+      }
+      i++;
+    }
+    // should never get here
+    dReportBug("should never get here");
+  }
+
+  // with argument, find matching help browser
+  while (heHelpBrowsers[i].browser != NULL &&
+         strcmp(heHelpBrowsers[i].browser, which) != 0)
+  {i++;}
+
+  if (heHelpBrowsers[i].browser == NULL)
+  {
+    if (warn) Warn("No help browser '%s' available.", which);
+  }
+  else
+  {
+    // see whether we can init it
+    if (heHelpBrowsers[i].init_proc(warn,i))
+    {
+      heCurrentHelpBrowser = &(heHelpBrowsers[i]);
+      heCurrentHelpBrowserIndex=i;
+      goto Finish;
+    }
+  }
+
+  // something went wrong
+  if (heCurrentHelpBrowser == NULL)
+  {
+    feHelpBrowser();
+    assume(heCurrentHelpBrowser != NULL);
+    if (warn)
+      Warn("Setting help browser to '%s'.", heCurrentHelpBrowser->browser);
+    return heCurrentHelpBrowser->browser;
+  }
+  else
+  {
+    // or, leave as is
+    if (warn)
+      Warn("Help browser stays at '%s'.",  heCurrentHelpBrowser->browser);
+    return heCurrentHelpBrowser->browser;
+  }
+
+  Finish:
+  // update value of Browser Option
+  if (feOptSpec[FE_OPT_BROWSER].value == NULL ||
+      strcmp((char*) feOptSpec[FE_OPT_BROWSER].value,
+             heCurrentHelpBrowser->browser) != 0)
+  {
+    omfree(feOptSpec[FE_OPT_BROWSER].value);
+    feOptSpec[FE_OPT_BROWSER].value
+     = (void*) omStrDup(heCurrentHelpBrowser->browser);
+  }
+  return heCurrentHelpBrowser->browser;
+}
+
+void  feStringAppendBrowsers(int warn)
+{
+  int i;
+  StringAppendS("Available HelpBrowsers: ");
+
+  i = 0;
+  if (heHelpBrowsers==NULL) feBrowserFile();
+  while (heHelpBrowsers[i].browser != NULL)
+  {
+    if (heHelpBrowsers[i].init_proc(warn,i))
+      StringAppend("%s, ", heHelpBrowsers[i].browser);
+    i++;
+  }
+  StringAppend("\nCurrent HelpBrowser: %s ", feHelpBrowser());
+}
+
+
+/*****************************************************************
+ *
+ * Implementation: local function
+ *
+ *****************************************************************/
+// Remove whitspaces from beginning and end, return NULL if only whitespaces
+static char* strclean(char* str)
+{
+  if (str == NULL) return NULL;
+  char *s=str;
+  while (*s <= ' ' && *s != '\0') s++;
+  if (*s == '\0') return NULL;
+  char *ss=s;
+  while (*ss!='\0') ss++;
+  ss--;
+  while (*ss <= ' ' && *ss != '\0')
+  {
+    *ss='\0';
+    ss--;
+  }
+  if (*ss == '\0') return NULL;
+  return s;
+}
+
+// Finds help entry for key:
+// returns filled-in hentry and TRUE, on success
+// FALSE, on failure
+// Assumes that lines of idx file have the following form
+// key\tnode\turl\tchksum\n (chksum ma be empty, then it is set to -1)
+// and that lines are sorted alpahbetically w.r.t. index entries
+static BOOLEAN heKey2Entry(char* filename, char* key, heEntry hentry)
+{
+  FILE* fd;
+  char c, k;
+  int kl, i;
+  *(hentry->key) = '\0';
+  *(hentry->url) = '\0';
+  *(hentry->node) = '\0';
+  hentry->chksum = 0;
+  if (filename == NULL || key == NULL)  return FALSE;
+  fd = fopen(filename, "r");
+  if (fd == NULL) return FALSE;
+  kl = strlen(key);
+
+  k = key[0];
+  i = 0;
+  while ((c = getc(fd)) != EOF)
+  {
+    if (c < k)
+    {
+      /* Skip line */
+      while (getc(fd) != '\n') {};
+      if (i)
+      {
+        i=0;
+        k=key[0];
+      }
+    }
+    else if (c == k)
+    {
+      i++;
+      if (i == kl)
+      {
+        // \t must follow, otherwise only substring match
+        if (getc(fd) != '\t') goto Failure;
+
+        // Now we found an exact match
+        if (hentry->key != key) strcpy(hentry->key, key);
+        // get node
+        i = 0;
+        while ((c = getc(fd)) != '\t' && c != EOF)
+        {
+          hentry->node[i] = c;
+          i++;
+        }
+        if (c == EOF) goto Failure;
+
+        // get url
+        hentry->node[i] = '\0';
+        i = 0;
+        while ((c = getc(fd)) != '\t' && c != EOF)
+        {
+          hentry->url[i] = c;
+          i++;
+        }
+        if (c == EOF) goto Failure;
+
+        // get chksum
+        hentry->url[i] = '\0';
+
+        if (fscanf(fd, "%ld\n", &(hentry->chksum)) != 1)
+        {
+          hentry->chksum = -1;
+        }
+        fclose(fd);
+        return TRUE;
+      }
+      else if (i > kl)
+      {
+        goto Failure;
+      }
+      else
+      {
+        k = key[i];
+      }
+    }
+    else
+    {
+      goto Failure;
+    }
+  }
+  Failure:
+  fclose(fd);
+  return FALSE;
+}
+
+// return TRUE if s matches re
+// FALSE, otherwise
+// does not distinguish lower and upper cases
+// inteprets * as wildcard
+static BOOLEAN strmatch(char* s, char* re)
+{
+  if (s == NULL || *s == '\0')
+    return (re == NULL || *re == '\0' || strcmp(re, "*") == 0);
+  if (re == NULL || *re == '\0') return FALSE;
+
+  int i;
+  char ls[MAX_HE_ENTRY_LENGTH + 1];
+  char rs[MAX_HE_ENTRY_LENGTH + 1];
+  char *l, *r, *ll, *rr;
+
+  // make everything to lower case
+  i=1;
+  ls[0] = '\0';
+  do
+  {
+    if (*s >= 'A' && *s <= 'Z') ls[i] = *s + ('a' - 'A');
+    else ls[i] = *s;
+    i++;
+    s++;
+  } while (*s != '\0');
+  ls[i] = '\0';
+  l = &(ls[1]);
+
+  i=1;
+  rs[0] = '\0';
+  do
+  {
+    if (*re >= 'A' && *re <= 'Z') rs[i]= *re + ('a' - 'A');
+    else rs[i] = *re;
+    i++;
+    re++;
+  } while (*re != '\0');
+  rs[i] = '\0';
+  r = &(rs[1]);
+
+  // chopp of exact matches from beginning and end
+  while (*r != '*' && *r != '\0' && *l != '\0')
+  {
+    if (*r != *l) return FALSE;
+    *r = '\0';
+    *s = '\0';
+    r++;
+    l++;
+  }
+  if (*r == '\0') return (*l == '\0');
+  if (*r == '*' && r[1] == '\0') return TRUE;
+  if (*l == '\0') return FALSE;
+
+  rr = &r[strlen(r) - 1];
+  ll = &l[strlen(l) - 1];
+  while (*rr != '*' && *rr != '\0' && *ll != '\0')
+  {
+    if (*rr != *ll) return FALSE;
+    *rr = '\0';
+    *ll = '\0';
+    rr--;
+    ll--;
+  }
+  if (*rr == '\0') return (*ll == '\0');
+  if (*rr == '*' && rr[-1] == '\0') return TRUE;
+  if (*ll == '\0') return FALSE;
+
+  // now *r starts with a * and ends with a *
+  r++;
+  *rr = '\0'; rr--;
+  while (*r != '\0')
+  {
+    rr = r + 1;
+    while (*rr != '*' && *rr != '\0') rr++;
+    if (*rr == '*')
+    {
+      *rr = '\0';
+      rr++;
+    }
+    l = strstr(l, r);
+    if (l == NULL) return FALSE;
+    r = rr;
+  }
+  return TRUE;
+}
+
+// similar to heKey2Entry, except that
+// key is taken as regexp (see above)
+// and number of matches is returned
+// if number of matches > 0, then hentry contains entry for first match
+// if number of matches > 1, matches are printed as komma-separated
+// into global string
+static int heReKey2Entry (char* filename, char* key, heEntry hentry)
+{
+  int i = 0;
+  FILE* fd;
+  char index_key[MAX_HE_ENTRY_LENGTH];
+
+  if (filename == NULL || key == NULL)  return 0;
+  fd = fopen(filename, "r");
+  if (fd == NULL) return 0;
+  while (fscanf(fd, "%[^\t]\t%*[^\n]\n", index_key) == 1)
+  {
+    if (strmatch(index_key, key))
+    {
+      i++;
+      if (i == 1)
+      {
+        heKey2Entry(filename, index_key, hentry);
+      }
+      else if (i == 2)
+      {
+        StringAppend("?%s; ?%s;", hentry->key, index_key);
+      }
+      else
+      {
+        StringAppend(" ?%s;", index_key);
+      }
+    }
+  }
+  fclose(fd);
+  return i;
+}
+
+/*****************************************************************
+ *
+ * Implementation : Help Browsers
+ *
+ *****************************************************************/
+
+static BOOLEAN feHelpCalled = FALSE;
+
+static void heBrowserHelp(heEntry hentry)
+{
+  // check checksums of procs
+  int kchksum = (hentry != NULL && hentry->chksum > 0 ?
+                 heKeyChksum(hentry->key) : 0);
+  if (kchksum  && kchksum != hentry->chksum && heOnlineHelp(hentry->key))
+    return;
+
+  if (heCurrentHelpBrowser == NULL) feHelpBrowser(NULL, 0);
+  assume(heCurrentHelpBrowser != NULL);
+  if (! feHelpCalled)
+  {
+    Warn("Displaying help in browser '%s'.", heCurrentHelpBrowser->browser);
+    if (strcmp(heCurrentHelpBrowser->browser, "netscape") == 0 &&
+        feResource('h', 0) == NULL)
+    {
+      Warn("Using URL '%s'.", feResource('u', 0));
+    }
+    Warn("Use 'system(\"--browser\", <browser>);' to change browser,");
+    char* browsers = StringSetS("where <browser> can be: ");
+    int i = 0;
+    i = 0;
+    while (heHelpBrowsers[i].browser != NULL)
+    {
+      if (heHelpBrowsers[i].init_proc(0,i))
+        StringAppend("\"%s\", ", heHelpBrowsers[i].browser);
+      i++;
+    }
+    if (browsers[strlen(browsers)-2] == ',')
+    {
+      browsers[strlen(browsers)-2] = '.';
+      browsers[strlen(browsers)-1] = '\0';
+    }
+    WarnS(browsers);
+  }
+
+  heCurrentHelpBrowser->help_proc(hentry, heCurrentHelpBrowserIndex);
+  feHelpCalled = TRUE;
+}
+
+#define MAX_SYSCMD_LEN MAXPATHLEN*2
+static BOOLEAN heGenInit(int warn, int br)
+{
+  if (heHelpBrowsers[br].required==NULL) return TRUE;
+  char *p=heHelpBrowsers[br].required;
+  while (*p>'\0')
+  {
+    switch (*p)
+    {
+      case '#': break;
+      case ' ': break;
+      case 'i': /* singular.hlp */
+      case 'x': /* singular.idx */
+      case 'h': /* html dir */
+               if (feResource(*p, warn) == NULL)
+               {
+                 if (warn) Warn("ressource `%c` not found",*p);
+                 return FALSE;
+               }
+               break;
+      case 'D': /* DISPLAY */
+               if (getenv("DISPLAY") == NULL)
+               {
+                 if (warn) WarnS("ressource `D` not found");
+                 return FALSE;
+               }
+               break;
+      case 'E': /* executable: E:xterm: */
+               {
+                 char name[128];
+                 char exec[128];
+                 memset(name,0,128);
+                 int i=0;
+                 p++;
+                 while (((*p==':')||(*p<=' ')) && (*p!='\0')) p++;
+                 while((i<127) && (*p>' ') && (*p!=':'))
+                 {
+                   name[i]=*p; p++; i++;
+                 }
+                 if (i==0) return FALSE;
+                 if (omFindExec(name,exec)==NULL)
+                 {
+                   if (warn) Warn("executable `%s` not found",name);
+                   return FALSE;
+                 }
+               }
+               break;
+      default: Warn("unknown char %c",*p);
+               break;
+    }
+    p++;
+  }
+  return TRUE;
+}
+#ifdef ix86_Win
+static void heHtmlHelp(heEntry hentry, int br)
+{
+  char url[MAXPATHLEN];
+  char* html_dir = feResource('h' /*"HtmlDir"*/);
+  sprintf(url, "%s/%s",
+          (html_dir != NULL ? html_dir : feResource('u' /*"ManualUrl"*/)),
+          (hentry!=NULL && *(hentry->url)!='\0' ? hentry->url : "index.htm"));
+
+  heOpenWinntUrl(url, (html_dir != NULL ? 1 : 0));
+}
+
+static void heWinHelp(heEntry hentry, int br)
+{
+  char keyw[MAX_HE_ENTRY_LENGTH];
+  if ((hentry!=NULL)&&(hentry->key!=NULL))
+    strcpy(keyw,hentry->key);
+  else
+    strcpy(keyw," ");
+  char* helppath = feResource('h' /*"HtmlDir"*/);
+  const char *filename="/Manual.hlp";
+  int helppath_len=0;
+  if (helppath!=NULL) helppath_len=strlen(helppath);
+  char *callpath=(char *)omAlloc0(helppath_len+strlen(filename)+1);
+  if ((helppath!=NULL) && (*helppath>' '))
+    strcpy(callpath,helppath);
+  strcat(callpath,filename);
+  heOpenWinntHlp(keyw,callpath);
+  omfree(callpath);
+}
+#endif
+static void heGenHelp(heEntry hentry, int br)
+{
+  char sys[MAX_SYSCMD_LEN];
+  char url[MAXPATHLEN];
+  char *p=heHelpBrowsers[br].action;
+  if (p==NULL) {PrintS("no action ?\n"); return;}
+  memset(sys,0,MAX_SYSCMD_LEN);
+  int i=0;
+  while ((*p>'\0')&& (i<MAX_SYSCMD_LEN))
+  {
+    if ((*p)=='%')
+    {
+      p++;
+      switch (*p)
+      {
+        case 'f': /* local html:file */
+        case 'h': /* local html:URL */
+        case 'H': /* www html */
+                 {
+                   char temp[256];
+                   char *htmldir = feResource('h' /*"HtmlDir"*/);
+                   if ((*p=='h')&&(htmldir!=NULL))
+                     strcat(sys,"file://localhost");
+                   else if ((*p=='H')||(htmldir==NULL))
+                     htmldir = feResource('u' /* %H -> "ManualUrl"*/);
+                     /* always defined */
+                   if (hentry != NULL && *(hentry->url) != '\0')
+                   #ifdef HAVE_VSNPRINTF
+                     snprintf(temp,256,"%s/%s", htmldir, hentry->url);
+                   else
+                     snprintf(temp,256,"%s/index.htm", htmldir);
+                   #else
+                     sprintf(temp,"%s/%s", htmldir, hentry->url);
+                   else
+                     sprintf(temp,"%s/index.htm", htmldir);
+                   #endif
+                   strcat(sys,temp);
+                   if ((*p)=='f')
+                   { // remove #SEC
+                     char *pp=strchr(sys,'#');
+                     if (pp!=NULL)
+		     { 
+		       *pp='\0';
+                       i=strlen(sys);
+		       memset(pp,0,MAX_SYSCMD_LEN-i);
+		     }  
+                   }
+                   i=strlen(sys);
+                   break;
+                 }
+        case 'i': /* singular.hlp */
+                 {
+                   char *i_res=feResource('i');
+                   if (i_res!=NULL) strcat(sys,i_res);
+                   else
+                   {
+                     WarnS("singular.hlp not found");
+                     return;
+                   }
+                   i=strlen(sys);
+                   break;
+                 }
+        case 'n': /* info node */
+                 {
+                   char temp[256];
+                   if ((hentry!=NULL) && (*(hentry->node) != '\0'))
+                     sprintf(temp,"%s",hentry->node);
+                   //else if ((hentry!=NULL) && (hentry->key!=NULL))
+                   //  sprintf(temp,"Index '%s'",hentry->key);
+                   else
+                     sprintf(temp,"Top");
+                   strcat(sys,temp);
+                   i=strlen(sys);
+                   break;
+                 }
+        default: break;
+      }
+      p++;
+    }
+    else
+    {
+      sys[i]=*p;
+      p++;i++;
+    }
+  }
+  Print("running `%s`\n",sys);
+  system(sys);
+}
+
+#ifdef ix86_Win
+static void heHtmlHelp(heEntry hentry)
+{
+  char url[MAXPATHLEN];
+  char* html_dir = feResource('h' /*"HtmlDir"*/);
+  sprintf(url, "%s/%s",
+          (html_dir != NULL ? html_dir : feResource('u' /*"ManualUrl"*/)),
+          (hentry!=NULL && *(hentry->url)!='\0' ? hentry->url : "index.htm"));
+
+  heOpenWinntUrl(url, (html_dir != NULL ? 1 : 0));
+}
+
+static void heWinHelp(heEntry hentry)
+{
+  char keyw[MAX_HE_ENTRY_LENGTH];
+  if ((hentry!=NULL)&&(hentry->key!=NULL))
+    strcpy(keyw,hentry->key);
+  else
+    strcpy(keyw," ");
+  char* helppath = feResource('h' /*"HtmlDir"*/);
+  const char *filename="/Manual.hlp";
+  int helppath_len=0;
+  if (helppath!=NULL) helppath_len=strlen(helppath);
+  char *callpath=(char *)omAlloc0(helppath_len+strlen(filename)+1);
+  if ((helppath!=NULL) && (*helppath>' '))
+    strcpy(callpath,helppath);
+  strcat(callpath,filename);
+  heOpenWinntHlp(keyw,callpath);
+  omfree(callpath);
+}
+#endif
+
+static BOOLEAN heDummyInit(int warn, int br)
+{
+  return TRUE;
+}
+static void heDummyHelp(heEntry hentry, int br)
+{
+  Werror("No functioning help browser available.");
+}
+
+static BOOLEAN heEmacsInit(int warn, int br)
+{
+  return TRUE;
+}
+static void heEmacsHelp(heEntry hentry, int br)
+{
+  WarnS("Your help command could not be executed. Use");
+  Warn("C-h C-s %s",
+       (hentry != NULL && *(hentry->node) != '\0' ? hentry->node : "Top"));
+  Warn("to enter the Singular online help. For general");
+  Warn("information on Singular running under Emacs, type C-h m.");
+}
+static int singular_manual(char *str);
+static void heBuiltinHelp(heEntry hentry, int br)
+{
+  char* node = omStrDup(hentry != NULL && *(hentry->node) != '\0' ?
+                       hentry->node : "Top");
+  singular_manual(node);
+  omFree(node);
+}
+
+
+/* ========================================================================== */
+// old, stupid builtin_help
+// This could be implemented much more clever, but I'm too lazy to do this now
+//
+#define HELP_OK        0
+#define FIN_INDEX    '\037'
+#define HELP_NOT_OPEN  1
+#define HELP_NOT_FOUND 2
+#define BUF_LEN        256
+#define IDX_LEN        64
+#define MAX_LINES      21
+
+static inline char tolow(char p)
+{
+  if (('A'<=p)&&(p<='Z')) return p | 040;
+  return p;
+}
+
+/*************************************************/
+static int show(unsigned long offset,FILE *help, char *close)
+{ char buffer[BUF_LEN+1];
+  int  lines = 0;
+
+  if( help== NULL)
+    if( (help = fopen(feResource('i'), "rb")) == NULL)
+      return HELP_NOT_OPEN;
+
+  fseek(help,  (long)(offset+1), (int)0);
+  while( !feof(help)
+        && *fgets(buffer, BUF_LEN, help) != EOF
+        && buffer[0] != FIN_INDEX)
+  {
+    printf("%s", buffer);
+    if(lines++> MAX_LINES)
+    {
+      printf("\n Press <RETURN> to continue or x to exit help.\n");
+      fflush(stdout);
+      *close = (char)getchar();
+      if(*close=='x')
+      {
+        getchar();
+        break;
+      }
+      lines=0;
+    }
+  }
+  if(*close!='x')
+  {
+    printf("\nEnd of part. Press <RETURN> to continue or x to exit help.\n");
+    fflush(stdout);
+    *close = (char)getchar();
+    if(*close=='x')
+      getchar();
+  }
+  return HELP_OK;
+}
+
+/*************************************************/
+static int singular_manual(char *str)
+{ FILE *index=NULL,*help=NULL;
+  unsigned long offset;
+  char *p,close;
+  int done = 0;
+  char buffer[BUF_LEN+1],
+       Index[IDX_LEN+1],
+       String[IDX_LEN+1];
+
+  if( (index = fopen(feResource('i'), "rb")) == NULL)
+  {
+    return HELP_NOT_OPEN;
+  }
+
+  for(p=str; *p; p++) *p = tolow(*p);/* */
+  do
+  {
+    p--;
+  }
+  while ((p != str) && (*p<=' '));
+  p++;
+  *p='\0';
+  (void)sprintf(String, " %s ", str);
+
+  while(!feof(index)
+        && fgets(buffer, BUF_LEN, index) != (char *)0
+        && buffer[0] != FIN_INDEX);
+
+  while(!feof(index))
+  {
+    (void)fgets(buffer, BUF_LEN, index); /* */
+    (void)sscanf(buffer, "Node:%[^\177]\177%ld\n", Index, &offset);
+    for(p=Index; *p; p++) *p = tolow(*p);/* */
+    (void)strcat(Index, " ");
+    if( strstr(Index, String)!=NULL)
+    {
+      done++; (void)show(offset, help, &close);
+    }
+    Index[0]='\0';
+    if(close=='x')
+    break;
+  }
+  if (index != NULL) (void)fclose(index);
+  if (help != NULL) (void)fclose(help);
+  if(! done)
+  {
+    Warn("`%s` not found",String);
+    return HELP_NOT_FOUND;
+  }
+  return HELP_OK;
+}
+/*************************************************/
Index: kernel/feread.cc
===================================================================
--- kernel/feread.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/feread.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,394 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: feread.cc,v 1.1.1.1 2003-10-06 12:15:52 Singular Exp $ */
+/*
+* ABSTRACT: input from ttys, simulating fgets
+*/
+
+#include "mod2.h"
+
+// ----------------------------------------
+// system settings:
+
+#undef USE_READLINE4
+
+
+//----------------------------------------
+#ifdef ix86_Win
+#define READLINE_STATIC
+#endif
+#include "febase.h"
+#ifdef ix86_Win
+#define OM_NO_MALLOC_MACROS
+#endif
+#ifdef ppcMac_darwin
+#define OM_NO_MALLOC_MACROS
+#endif
+#include "omalloc.h"
+
+#include "../Singular/static.h"
+
+#ifdef HAVE_STATIC
+#undef HAVE_DYN_RL
+#endif
+
+#ifdef ix86_Linux
+#undef HAVE_FEREAD
+// not compatible with glibc2
+#endif
+
+#if defined(HAVE_DYN_RL)
+#include <unistd.h>
+#endif
+
+static char * fe_fgets_stdin_init(char *pr,char *s, int size);
+char * (*fe_fgets_stdin)(char *pr,char *s, int size)
+ = fe_fgets_stdin_init;
+
+/* ===================================================================*/
+/* =                   static/dymanic readline                      = */
+/* ===================================================================*/
+#if defined(HAVE_READLINE) || defined(HAVE_DYN_RL)
+
+#include "../Singular/ipshell.h"
+
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+
+/* Generator function for command completion.  STATE lets us know whether
+*   to start from scratch; without any state (i.e. STATE == 0), then we
+*   start at the top of the list.
+*/
+extern "C"
+char *command_generator (char *text, int state)
+{
+  static int list_index, len;
+  char *name;
+
+  /* If this is a new word to complete, initialize now.  This includes
+     saving the length of TEXT for efficiency, and initializing the index
+     variable to 0. */
+  if (state==0)
+  {
+    list_index = 1;
+    len = strlen (text);
+  }
+
+  /* Return the next name which partially matches from the command list. */
+  while ((name = cmds[list_index].name)!=NULL)
+  {
+    list_index++;
+
+    if (strncmp (name, text, len) == 0)
+      return (strdup(name));
+  }
+
+  /* If no names matched, then return NULL. */
+  return ((char *)NULL);
+}
+#endif
+
+/* ===================================================================*/
+/* =                      static readline                           = */
+/* ===================================================================*/
+/* some procedure are shared with "dynamic readline" */
+#if defined(HAVE_READLINE) && !defined(HAVE_FEREAD)
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+
+// #undef READLINE_READLINE_H_OK
+
+extern "C" {
+  typedef char * (*RL_PROC)(const char*,int);
+ #ifdef READLINE_READLINE_H_OK
+  #include <readline/readline.h>
+  #ifdef HAVE_READLINE_HISTORY_H
+   #include <readline/history.h>
+  
+  #endif
+#endif
+#ifdef RL_VERSION_MAJOR
+#if (RL_VERSION_MAJOR >= 4)
+#define USE_READLINE4
+#endif
+#endif
+#ifndef USE_READLINE4
+#define rl_filename_completion_function filename_completion_function
+#define rl_completion_matches           completion_matches
+#endif
+#ifndef READLINE_READLINE_H_OK  
+ /* declare everything we need explicitely and do not rely on includes */
+  extern char * rl_readline_name;
+  extern char *rl_line_buffer;
+  char *rl_filename_completion_function(const char*, int);
+  typedef char **CPPFunction ();
+
+  extern char ** rl_completion_matches (const char*, RL_PROC);
+  extern CPPFunction * rl_attempted_completion_function;
+  extern FILE * rl_outstream;
+  extern char * readline ();
+  extern void add_history ();
+  extern int write_history ();
+  extern void using_history();
+  extern int read_history();
+  extern int history_total_bytes();
+ #endif /* READLINE_READLINE_H_OK */
+ typedef char * (*PROC)();
+
+  typedef char **RL_CPPFunction (const char*, int,int);
+}
+
+
+char * fe_fgets_stdin_rl(char *pr,char *s, int size);
+
+/* Tell the GNU Readline library how to complete.  We want to try to complete
+   on command names  or on filenames if it is preceded by " */
+
+/* Attempt to complete on the contents of TEXT.  START and END show the
+*   region of TEXT that contains the word to complete.  We can use the
+*   entire line in case we want to do some simple parsing.  Return the
+*   array of matches, or NULL if there aren't any.
+*/
+char ** singular_completion (char *text, int start, int end)
+{
+  /* If this word is not in a string, then it may be a command
+     to complete.  Otherwise it may be the name of a file in the current
+     directory. */
+  if (rl_line_buffer[start-1]=='"')
+    return rl_completion_matches (text, (RL_PROC)rl_filename_completion_function);
+  char **m=rl_completion_matches (text, (RL_PROC)command_generator);
+  if (m==NULL)
+  {
+    m=(char **)malloc(2*sizeof(char*));
+    m[0]=(char *)malloc(end-start+2);
+    strncpy(m[0],text,end-start+1);
+    m[1]=NULL;
+  }
+  return m;
+}
+
+char * fe_fgets_stdin_rl(char *pr,char *s, int size)
+{
+  if (!BVERBOSE(V_PROMPT))
+  {
+    pr="";
+  }
+  mflush();
+
+  char *line;
+  line = readline (pr);
+
+  if (line==NULL)
+    return NULL;
+
+  if (*line!='\0')
+  {
+    add_history (line);
+  }
+  int l=strlen(line);
+  if (l>=size-1)
+  {
+    strncpy(s,line,size);
+  }
+  else
+  {
+    strncpy(s,line,l);
+    s[l]='\n';
+    s[l+1]='\0';
+  }
+  free (line);
+
+  return s;
+}
+#endif
+
+/* ===================================================================*/
+/* =                    emulated readline                           = */
+/* ===================================================================*/
+#if !defined(HAVE_READLINE) && defined(HAVE_FEREAD)
+extern "C" {
+char * fe_fgets_stdin_fe(char *pr,char *s, int size);
+}
+char * fe_fgets_stdin_emu(char *pr,char *s, int size)
+{
+  if (!BVERBOSE(V_PROMPT))
+  {
+    pr="";
+  }
+  mflush();
+  return fe_fgets_stdin_fe(pr,s,size);
+}
+#endif
+
+/* ===================================================================*/
+/* =                     dynamic readline                           = */
+/* ===================================================================*/
+/* some procedure are shared with "static readline" */
+#if defined(HAVE_DYN_RL)
+extern "C" 
+{
+  extern void * fe_rl_hdl;
+  extern char ** fe_rl_readline_name;
+  char * fe_fgets_stdin_rl(char *pr,char *s, int size);
+  int fe_init_dyn_rl();
+  extern FILE ** fe_rl_outstream;
+  void (*fe_add_history)(char *);
+  char * (*fe_readline)(char *);
+}
+
+char * fe_fgets_stdin_drl(char *pr,char *s, int size)
+{
+  if (!BVERBOSE(V_PROMPT))
+  {
+    pr="";
+  }
+  mflush();
+
+  char *line;
+  line = (*fe_readline) (pr);
+
+  if (line==NULL)
+    return NULL;
+
+  if (*line!='\0')
+  {
+    (*fe_add_history) (line);
+  }
+  int l=strlen(line);
+  if (l>=size-1)
+  {
+    strncpy(s,line,size);
+  }
+  else
+  {
+    strncpy(s,line,l);
+    s[l]='\n';
+    s[l+1]='\0';
+  }
+  free (line);
+
+  return s;
+}
+#endif
+
+/* ===================================================================*/
+/* =                        fgets                                   = */
+/* ===================================================================*/
+char * fe_fgets(char *pr,char *s, int size)
+{
+  if (BVERBOSE(V_PROMPT))
+  {
+    fprintf(stdout,pr);
+  }
+  mflush();
+  return fgets(s,size,stdin);
+}
+
+/* ===================================================================*/
+/* =       init for static rl, dyn. rl, emu. rl                     = */
+/* ===================================================================*/
+static char * fe_fgets_stdin_init(char *pr,char *s, int size)
+{
+#if defined(HAVE_READLINE) && !defined(HAVE_FEREAD)
+  /* Allow conditional parsing of the ~/.inputrc file. */
+  rl_readline_name = "Singular";
+  /* Tell the completer that we want a crack first. */
+#ifdef USE_READLINE4
+  rl_attempted_completion_function = (rl_completion_func_t *)singular_completion;
+#else
+  rl_attempted_completion_function = (CPPFunction *)singular_completion;
+#endif
+
+  /* set the output stream */
+  if(!isatty(STDOUT_FILENO))
+  {
+    #ifdef atarist
+      rl_outstream = fopen( "/dev/tty", "w" );
+    #else
+      rl_outstream = fopen( ttyname(fileno(stdin)), "w" );
+    #endif
+  }
+
+  /* try to read a history */
+  using_history();
+  char *p = getenv("SINGULARHIST");
+  if (p != NULL)
+  {
+    read_history (p);
+  }
+  fe_fgets_stdin=fe_fgets_stdin_rl;
+  return(fe_fgets_stdin_rl(pr,s,size));
+#endif
+#ifdef HAVE_DYN_RL
+  /* do dynamic loading */
+  int res=fe_init_dyn_rl();
+  if (res!=0)
+  {
+    //if (res==1)
+    //  WarnS("dynamic loading of libreadline failed");
+    //else
+    //  Warn("dynamic loading failed: %d\n",res);
+    if (res!=1)
+      Warn("dynamic loading failed: %d\n",res);
+    #ifdef HAVE_FEREAD
+    fe_fgets_stdin=fe_fgets_stdin_emu;
+    #else
+    fe_fgets_stdin=fe_fgets;
+    #endif
+    return fe_fgets_stdin(pr,s,size);
+  }
+
+  /* set the output stream */
+  if(!isatty(STDOUT_FILENO))
+  {
+    #ifdef atarist
+      *fe_rl_outstream = fopen( "/dev/tty", "w" );
+    #else
+      *fe_rl_outstream = fopen( ttyname(fileno(stdin)), "w" );
+    #endif
+  }
+
+  fe_fgets_stdin=fe_fgets_stdin_drl;
+  return fe_fgets_stdin_drl(pr,s,size);
+#else
+  #if !defined(HAVE_READLINE) && defined(HAVE_FEREAD)
+    fe_fgets_stdin=fe_fgets_stdin_emu;
+    return(fe_fgets_stdin_emu(pr,s,size));
+  #else
+    fe_fgets_stdin=fe_fgets;
+    return(fe_fgets(pr,s,size));
+  #endif
+#endif
+}
+
+/* ===================================================================*/
+/* =                          TCL                                   = */
+/* ===================================================================*/
+#ifdef HAVE_TCL
+/* tcl: */
+char * fe_fgets_tcl(char *pr,char *s, int size)
+{
+  if(currRing!=NULL) PrintTCLS('P',pr);
+  else               PrintTCLS('U',pr);
+  mflush();
+  return fgets(s,size,stdin);
+}
+
+#endif
+
+/* ===================================================================*/
+/* =                      batch mode                                = */
+/* ===================================================================*/
+/* dummy (for batch mode): */
+char * fe_fgets_dummy(char *pr,char *s, int size)
+{
+  return NULL;
+}
+
Index: kernel/fereadl.c
===================================================================
--- kernel/fereadl.c	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/fereadl.c	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,960 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: fereadl.c,v 1.1.1.1 2003-10-06 12:15:52 Singular Exp $ */
+/*
+* ABSTRACT: input from ttys, simulating fgets
+*/
+
+
+#include "mod2.h"
+#include "febase.h"
+#include "omalloc.h"
+#include "structs.h"
+#include "febase.h"
+
+#ifdef HAVE_FEREAD
+  #include <unistd.h>
+  #include <stdio.h>
+  #include <stdlib.h>
+  #include <sys/time.h>
+  #include <sys/types.h>
+  #include <string.h>
+
+  #if 0
+    #include <pc.h>
+  #else
+    #ifdef SunOS_5
+      /* solaris special, found with v 5.7 */
+      #define _XOPEN_SOURCE_EXTENDED
+      #include "/usr/xpg4/include/term.h"
+    #endif
+    #if 0
+      #ifndef SunOS_5
+        #include <term.h>
+      #endif
+    #elif HAVE_TERMCAP_H
+      #ifndef SunOS_5
+      #include <termcap.h>
+      #endif
+    #endif
+    #if defined(HAVE_TERMIOS_H) && ! defined(TCSANOW)
+      #include <termios.h>
+    #endif
+    #if defined(HAVE_TERM_H) && ! defined(TCSANOW)
+      #include <term.h>
+    #endif
+
+    #ifdef atarist
+      #include <ioctl.h>
+    #else
+      #ifdef NeXT
+        #include <sgtty.h>
+        #include <sys/ioctl.h>
+      #endif
+    #endif
+  #endif
+
+
+#ifndef STDIN_FILENO
+  #define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+  #define STDOUT_FILENO 1
+#endif
+
+#define feCTRL(C) ((C) & 0x1F)    /* <ctrl> character  */
+
+#ifndef MSDOS
+
+  /* Use this variable to remember original terminal attributes. */
+  #if defined( atarist ) || defined( NeXT )
+    struct sgttyb  fe_saved_attributes;
+  #else
+    struct termios fe_saved_attributes;
+  #endif
+#endif
+
+static BOOLEAN fe_stdout_is_tty;
+static BOOLEAN fe_stdin_is_tty;
+BOOLEAN fe_use_fgets=FALSE;
+static BOOLEAN fe_is_initialized=FALSE;
+FILE *  fe_echo; /*the output file for echoed characters*/
+
+#define fe_hist_max 32
+char ** fe_hist=NULL;
+short   fe_hist_pos;
+BOOLEAN fe_is_raw_tty=0;
+int     fe_cursor_pos; /* 0..colmax-1*/
+int     fe_cursor_line; /* 0..pagelength-1*/
+
+#ifndef MSDOS
+  #ifndef HAVE_ATEXIT
+    int on_exit(void (*f)(int, void *), void *arg);
+    #ifdef HAVE_FEREAD
+      void fe_reset_fe (int i, void *v)
+    #endif
+  #else
+    #ifdef HAVE_FEREAD
+      void fe_reset_fe (void)
+    #endif
+  #endif
+  {
+    if (fe_stdin_is_tty)
+    {
+      int i;
+      if (fe_is_raw_tty)
+      {
+        #ifdef atarist
+          stty(0, &fe_saved_attributes);
+        #else
+          #ifdef NeXT
+            ioctl(STDIN_FILENO, TIOCSETP, &fe_saved_attributes);
+          #else
+            tcsetattr (STDIN_FILENO, TCSANOW, &fe_saved_attributes);
+          #endif
+        #endif
+        fe_is_raw_tty=0;
+      }
+      if (fe_hist!=NULL)
+      {
+        for(i=fe_hist_max-1;i>=0;i--)
+        {
+          if (fe_hist[i] != NULL) omFree((ADDRESS)fe_hist[i]);
+        }
+        omFreeSize((ADDRESS)fe_hist,fe_hist_max*sizeof(char *));
+        fe_hist=NULL;
+      }
+      if (!fe_stdout_is_tty)
+      {
+        fclose(fe_echo);
+      }
+    }
+  }
+  void fe_temp_reset (void)
+  {
+    if (fe_is_raw_tty)
+    {
+      #ifdef atarist
+        stty(0, &fe_saved_attributes);
+      #else
+        #ifdef NeXT
+          ioctl(STDIN_FILENO, TIOCSETP, &fe_saved_attributes);
+        #else
+          tcsetattr (STDIN_FILENO, TCSANOW, &fe_saved_attributes);
+        #endif
+      #endif
+      fe_is_raw_tty=0;
+    }
+  }
+  void fe_temp_set (void)
+  {
+    if(fe_is_raw_tty==0)
+    {
+      #ifdef atarist
+        /*set line wrap mode*/
+        if(fe_stdout_is_tty)
+        {
+          printf("\033v");
+        }
+      #endif
+      #if defined( atarist ) || defined( NeXT )
+        struct sgttyb tattr;
+      #else
+        struct termios tattr;
+      #endif
+
+      /* Set the funny terminal modes. */
+      #ifdef atarist
+         gtty(0, &tattr);
+         tattr.sg_flags |= RAW;
+         tattr.sg_flags |= CBREAK;
+         tattr.sg_flags &= ~ECHO;
+         stty(0, &tattr);
+      #else
+        #ifdef NeXT
+          ioctl(STDIN_FILENO, TIOCGETP, &tattr);
+          //tattr.sg_flags |= RAW;
+          tattr.sg_flags |= CBREAK;
+          tattr.sg_flags &= ~ECHO;
+          ioctl(STDIN_FILENO, TIOCSETP, &tattr);
+          ioctl(STDOUT_FILENO, TIOCGETP, &tattr);
+          tattr.sg_flags |= CRMOD;
+          ioctl(STDOUT_FILENO, TIOCSETP, &tattr);
+        #else
+          tcgetattr (STDIN_FILENO, &tattr);
+          tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
+          tattr.c_cc[VMIN] = 1;
+          tattr.c_cc[VTIME] = 0;
+          tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
+        #endif
+      #endif
+      fe_is_raw_tty=1;
+    }
+  }
+#endif
+
+static char termcap_buff[2048];
+static int fe_out_char(int c)
+{
+  fputc(c,fe_echo);
+  return c;
+}
+void fe_init (void)
+{
+  #ifdef MSDOS
+  /*extern short ospeed;*/
+  #endif
+  fe_is_initialized=TRUE;
+  if ((!fe_use_fgets) && (isatty (STDIN_FILENO)))
+  {
+    /* Make sure stdin is a terminal. */
+    #ifndef MSDOS
+      char *term=getenv("TERM");
+
+      /*setup echo*/
+      if(isatty(STDOUT_FILENO))
+      {
+        fe_stdout_is_tty=1;
+        fe_echo=stdout;
+      }
+      else
+      {
+        fe_stdout_is_tty=0;
+        #ifdef atarist
+          fe_echo = fopen( "/dev/tty", "w" );
+        #else
+          fe_echo = fopen( ttyname(fileno(stdin)), "w" );
+        #endif
+      }
+      /* Save the terminal attributes so we can restore them later. */
+      {
+        #if defined( atarist ) || defined( NeXT )
+          struct sgttyb tattr;
+          #ifdef atarist
+            gtty(0, &fe_saved_attributes);
+          #else
+            ioctl(STDIN_FILENO, TIOCGETP, &fe_saved_attributes);
+          #endif
+        #else
+          struct termios tattr;
+          tcgetattr (STDIN_FILENO, &fe_saved_attributes);
+        #endif
+        #ifdef HAVE_FEREAD
+          #ifdef HAVE_ATEXIT
+            atexit(fe_reset_fe);
+          #else
+            on_exit(fe_reset_fe,NULL);
+          #endif
+        #endif
+
+      /* Set the funny terminal modes. */
+        #ifdef atarist
+          gtty(0, &tattr);
+          tattr.sg_flags |= RAW;
+          tattr.sg_flags |= CBREAK;
+          tattr.sg_flags &= ~ECHO;
+          stty(0, &tattr);
+        #else
+          #ifdef NeXT
+            ioctl(STDIN_FILENO, TIOCGETP, &tattr);
+            //tattr.sg_flags |= RAW;
+            tattr.sg_flags |= CBREAK;
+            tattr.sg_flags &= ~ECHO;
+            ioctl(STDIN_FILENO, TIOCSETP, &tattr);
+            ioctl(STDOUT_FILENO, TIOCGETP, &tattr);
+            tattr.sg_flags |= CRMOD;
+            ioctl(STDOUT_FILENO, TIOCSETP, &tattr);
+          #else
+            tcgetattr (STDIN_FILENO, &tattr);
+            tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
+            tattr.c_cc[VMIN] = 1;
+            tattr.c_cc[VTIME] = 0;
+            tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
+          #endif
+          /*ospeed=cfgetospeed(&tattr);*/
+        #endif
+      }
+    #endif
+    if(term==NULL)
+    {
+      printf("need TERM\n");
+    }
+    else if(tgetent(termcap_buff,term)<=0)
+    {
+      printf("could not access termcap data base\n");
+    }
+    else
+    {
+      #ifndef ix86_Win
+      extern char *BC;
+      extern char *UP;
+      extern char PC;
+      #endif
+      /* OB: why this ? HS: char t_buf[128] does not work with glibc2 systems */
+      char *t_buf=(char *)omAlloc(128); 
+      /*char t_buf[128];*/
+      char *temp;
+
+      /* Extract information that termcap functions use.  */
+      temp = tgetstr ("pc", t_buf);
+      PC = (temp!=NULL) ? *temp : '\0';
+      BC=tgetstr("le",t_buf);
+      UP=tgetstr("up",t_buf);
+
+      /* Extract information we will use */
+      colmax=tgetnum("co");
+      pagelength=tgetnum("li");
+      fe_cursor_line=pagelength-1;
+
+      /* init screen */
+      temp = tgetstr ("ti", t_buf);
+      #if 0
+      if (temp!=NULL) tputs(temp,1,fe_out_char);
+      #endif
+
+      /* printf("TERM=%s, co=%d, li=%d\n",term,colmax,pagelength);*/
+    }
+
+    fe_stdin_is_tty=1;
+    fe_is_raw_tty=1;
+
+    /* setup history */
+    fe_hist=(char **)omAlloc0(fe_hist_max*sizeof(char *));
+    omMarkAsStaticAddr(fe_hist);
+    fe_hist_pos=0;
+  }
+  else
+  {
+    fe_stdin_is_tty=0;
+    fe_echo=stdout;
+  }
+}
+
+/* delete to end of line */
+static void fe_ctrl_k(char *s,int i)
+{
+  int j=i;
+  while(s[j]!='\0')
+  {
+    fputc(' ',fe_echo);
+    j++;
+  }
+  while(j>i)
+  {
+    fputc('\b',fe_echo);
+    j--;
+  }
+}
+
+/* delete the line */
+static void fe_ctrl_u(char *s,int *i)
+{
+  fe_ctrl_k(s,*i);
+  while((*i)>0)
+  {
+    (*i)--;
+    fputc('\b',fe_echo);
+    fputc(' ',fe_echo);
+    fputc('\b',fe_echo);
+  }
+}
+
+/*2
+* add s to the history
+* if s is no the previous one, duplicate it
+*/
+static void fe_add_hist(char *s)
+{
+  if (s[0]!='\0') /* skip empty lines */
+  {
+    /* compare this line*/
+    if (fe_hist_pos!=0)
+    {
+      if ((fe_hist[fe_hist_pos-1]!=NULL)
+      && (strcmp(fe_hist[fe_hist_pos-1],s)==0))
+        return;
+    }
+    else
+    {
+      if ((fe_hist[fe_hist_max-1]!=NULL)
+      && (strcmp(fe_hist[fe_hist_max-1],s)==0))
+        return;
+    }
+    /* normal case: enter a new line */
+    /* first free the slot at position fe_hist_pos */
+    if (fe_hist[fe_hist_pos]!=NULL)
+    {
+      omFree((ADDRESS)fe_hist[fe_hist_pos]);
+    }
+    /* and store a duplicate */
+    fe_hist[fe_hist_pos]=omStrDup(s);
+    omMarkAsStaticAddr(fe_hist[fe_hist_pos]);
+    /* increment fe_hist_pos in a circular manner */
+    fe_hist_pos++;
+    if (fe_hist_pos==fe_hist_max) fe_hist_pos=0;
+  }
+}
+
+static void fe_get_hist(char *s, int size, int *pos,int change, int incr)
+{
+  if (change)
+    fe_add_hist(s);
+  do
+  {
+    (*pos)+=incr;
+    if((*pos)>=fe_hist_max) (*pos)-=fe_hist_max;
+    else if((*pos)<0)       (*pos)+=fe_hist_max;
+  }
+  while (((*pos)!=0)&&(fe_hist[(*pos)]==NULL));
+  memset(s,0,size);
+  if (fe_hist[(*pos)]!=NULL)
+  {
+    strncpy(s,fe_hist[(*pos)],size-2);
+  }
+}
+
+static int fe_getchar()
+{
+  #ifndef MSDOS
+  char c='\0';
+  while (1!=read (STDIN_FILENO, &c, 1));
+  #else
+  int c=getkey();
+  #endif
+  #ifndef MSDOS
+  if (c == 033)
+  {
+    /* check for CSI */
+    c='\0';
+    read (STDIN_FILENO, &c, 1);
+    if (c == '[')
+    {
+      /* get command character */
+      c='\0';
+      read (STDIN_FILENO, &c, 1);
+      switch (c)
+      {
+        case 'D': /* left arrow key */
+          c = feCTRL('B')/*002*/;
+          break;
+        case 'C': /* right arrow key */
+          c = feCTRL('F')/*006*/;
+          break;
+        case 'A': /* up arrow key */
+          c = feCTRL('P')/*020*/;
+          break;
+        case 'B': /* down arrow key */
+          c = feCTRL('N')/*016*/;
+          break;
+      }
+    }
+  }
+  #endif
+  return c;
+}
+
+static void fe_set_cursor(char *s,int i)
+{
+  char tgoto_buf[40];
+  if (0)/*(fe_cursor_pos>1) && (i>0))*/
+  {
+    /*fputs(tgoto(tgetstr("cm",&tgoto_buf),fe_cursor_pos-1,fe_cursor_line),fe_echo);*/
+    tputs(
+      tgoto(tgetstr("cm",(char **)&tgoto_buf),fe_cursor_pos-1,fe_cursor_line),
+      pagelength,fe_out_char);
+    fputc(s[i-1],fe_echo);
+  }
+  else
+  {
+    /*fputs(
+      tgoto(tgetstr("cm",&tgoto_buf),fe_cursor_pos,fe_cursor_line),fe_echo);*/
+    tputs(tgoto(tgetstr("cm",(char **)&tgoto_buf),fe_cursor_pos,fe_cursor_line),
+      pagelength,fe_out_char);
+  }
+  fflush(fe_echo);
+}
+
+char * fe_fgets_stdin_fe(char *pr,char *s, int size)
+{
+  if(!fe_is_initialized)
+    fe_init();
+  if (fe_stdin_is_tty)
+  {
+    int h=fe_hist_pos;
+    int change=0;
+    #ifdef MSDOS
+      int c;
+    #else
+      char c;
+    #endif
+    int i=0;
+
+    if (fe_is_raw_tty==0)
+    {
+      fe_temp_set();
+    }
+
+    fputs(pr,fe_echo); fflush(fe_echo);
+    fe_cursor_pos=strlen(pr); /* prompt */
+
+    memset(s,0,size);
+
+    loop
+    {
+      c=fe_getchar();
+      switch(c)
+      {
+        case feCTRL('M'):
+        case feCTRL('J'):
+        {
+          fd_set fdset;
+          struct timeval tv;
+          int sel;
+
+          fe_add_hist(s);
+          i=strlen(s);
+          if (i<size-1) s[i]='\n';
+          fputc('\n',fe_echo);
+          fflush(fe_echo);
+
+          FD_ZERO (&fdset);
+          FD_SET(STDIN_FILENO, &fdset);
+          tv.tv_sec = 0;
+          tv.tv_usec = 0;
+          #ifdef hpux
+            sel = select (STDIN_FILENO+1, (int *)fdset.fds_bits, NULL, NULL, &tv);
+          #else
+            sel = select (STDIN_FILENO+1, &fdset, NULL, NULL, &tv);
+          #endif
+          if (sel==0)
+            fe_temp_reset();
+          return s;
+        }
+        #ifdef MSDOS
+        case 0x153:
+        #endif
+        case feCTRL('H'):
+        case 127:       /*delete the character left of the cursor*/
+        {
+          if (i==0) break;
+          i--;
+          fe_cursor_pos--;
+          if(fe_cursor_pos<0)
+          {
+            fe_cursor_line--;
+            fe_cursor_pos=colmax-1;
+            fe_set_cursor(s,i);
+          }
+          else
+          {
+            fputc('\b',fe_echo);
+          }
+          /* NO BREAK : next: feCTRL('D') */
+        }
+        case feCTRL('D'):  /*delete the character under the cursor or eof*/
+        {
+          int j;
+          if ((i==0) &&(s[0]=='\0')) return NULL; /*eof*/
+          if (s[i]!='\0')
+          {
+            j=i;
+            while(s[j]!='\0')
+            {
+              s[j]=s[j+1];
+              fputc(s[j],fe_echo);
+              j++;
+            }
+            fputc(' ',fe_echo);
+            if (fe_cursor_pos+(j-i)>=colmax)
+            {
+              fe_set_cursor(s,i);
+            }
+            else
+            {
+              while(j>i)
+              {
+                fputc('\b',fe_echo);
+                j--;
+              }
+            }
+          }
+          #ifdef MSDOS
+          fputc('\b',fe_echo);
+          #endif
+          change=1;
+          fflush(fe_echo);
+          break;
+        }
+        case feCTRL('A'):  /* move the cursor to the beginning of the line */
+        {
+          if (i>=colmax-strlen(pr))
+          {
+            while (i>=colmax-strlen(pr))
+            {
+              i-=colmax;
+              fe_cursor_line--;
+            }
+            i=0;
+            fe_cursor_pos=strlen(pr);
+            fe_set_cursor(s,i);
+          }
+          else
+          {
+            while(i>0)
+            {
+              i--;
+              fputc('\b',fe_echo);
+            }
+            fe_cursor_pos=strlen(pr);
+          }
+          break;
+        }
+        case feCTRL('E'): /* move the cursor to the end of the line */
+        {
+          while(s[i]!='\0')
+          {
+            fputc(s[i],fe_echo);
+            i++;
+            fe_cursor_pos++;
+            if(fe_cursor_pos>=colmax)
+            {
+              fe_cursor_pos=0;
+              if(fe_cursor_line!=(pagelength-1))
+                fe_cursor_line++;
+            }
+          }
+          break;
+        }
+        case feCTRL('B'): /* move the cursor backward one character */
+        {
+          if (i>0)
+          {
+            i--;
+            fputc('\b',fe_echo);
+            fe_cursor_pos--;
+            if(fe_cursor_pos<0)
+            {
+              fe_cursor_pos=colmax-1;
+              fe_cursor_line--;
+            }
+          }
+          break;
+        }
+        case feCTRL('F'): /* move the cursor forward  one character */
+        {
+          if(s[i]!='\0')
+          {
+            fputc(s[i],fe_echo);
+            i++;
+            fe_cursor_pos++;
+            if(fe_cursor_pos>=colmax)
+            {
+              fe_cursor_pos=0;
+              if(fe_cursor_line!=(pagelength-1))
+                fe_cursor_line++;
+            }
+          }
+          break;
+        }
+        case feCTRL('U'): /* delete entire input line */
+        {
+          fe_ctrl_u(s,&i);
+          fe_cursor_pos=strlen(pr);
+          memset(s,0,size);
+          change=1;
+          break;
+        }
+        #if 0
+        case feCTRL('W'): /* test hist. */
+        {
+          int i;
+          PrintS("\nstart hist\n");
+          for(i=0;i<fe_hist_max;i++)
+          {
+            if(fe_hist[i]!=NULL)
+            {
+              Print("%2d ",i);
+              if(i==fe_hist_pos) PrintS("-"); else PrintS(" ");
+              if(i==h) PrintS(">"); else PrintS(" ");
+              PrintS(fe_hist[i]);
+              PrintLn();
+            }
+          }
+          Print("end hist, next_pos=%d\n",fe_hist_pos);
+          break;
+        }
+        #endif
+        case feCTRL('K'): /* delete up to the end of the line */
+        {
+          fe_ctrl_k(s,i);
+          memset(&(s[i]),'\0',size-i);
+          /* s[i]='\0';*/
+          change=1;
+          break;
+        }
+        case feCTRL('L'): /* redraw screen */
+        {
+          char t_buf[40];
+          char *t=t_buf;
+          fe_cursor_line=i/colmax;
+          /*fputs(tgetstr("cl",&t),fe_echo);*/
+          tputs(tgetstr("cl",&t),pagelength,fe_out_char);
+          fflush(fe_echo);
+          fputs(pr,fe_echo);
+          fputs(s,fe_echo);
+          fe_set_cursor(s,i);
+          break;
+        }
+        case feCTRL('P'): /* previous line */
+        {
+          fe_ctrl_u(s,&i);
+          fe_get_hist(s,size,&h,change,-1);
+          while(s[i]!='\0')
+          {
+            fputc(s[i],fe_echo);
+            i++;
+          }
+          fe_cursor_pos=strlen(pr)+i/*strlen(s)*/;
+          change=0;
+          break;
+        }
+        case feCTRL('N'): /* next line */
+        {
+          fe_ctrl_u(s,&i);
+          fe_get_hist(s,size,&h,change,1);
+          while(s[i]!='\0')
+          {
+            fputc(s[i],fe_echo);
+            i++;
+          }
+          fe_cursor_pos=strlen(pr)+i/*strlen(s)*/;
+          change=0;
+          break;
+        }
+        default:
+        {
+          if ((c>=' ')&&(c<=126))
+          {
+            fputc (c,fe_echo);
+            fe_cursor_pos++;
+            if(fe_cursor_pos>=colmax)
+            {
+              fe_cursor_pos=0;
+              if(fe_cursor_line!=(pagelength-1))
+                fe_cursor_line++;
+            }
+            if (s[i]!='\0')
+            {
+              /* shift by 1 to the right */
+              int j=i;
+              int l;
+              while ((s[j]!='\0')&&(j<size-2)) j++;
+              l=j-i;
+              while (j>i) { s[j]=s[j-1]; j--; }
+              /* display */
+              fwrite(s+i+1,l,1,fe_echo);
+              fflush(fe_echo);
+              /* set cursor */
+              if(fe_cursor_pos+l>=colmax)
+              {
+                while(fe_cursor_pos+l>=colmax)
+                {
+                  fe_cursor_line--;
+                  l-=colmax;
+                }
+                fe_set_cursor(s,i);
+              }
+              else
+              {
+                while(l>0)
+                {
+                  l--;
+                  fputc('\b',fe_echo);
+                }
+              }
+              fflush(fe_echo);
+            }
+            if (i<size-1) s[i]=c;
+            i++;
+            change=1;
+          }
+        }
+      } /* switch */
+      fflush(fe_echo);
+    } /* loop */
+  }
+  /*else*/
+    return fgets(s,size,stdin);
+}
+
+//int main (void)
+//{
+//  char b[200];
+//  char * m_eof;
+//
+//  fe_init();
+//  while(1)
+//  {
+//    m_eof=fe_fgets_stdin_fe("> ",b,200);
+//    if (!m_eof) break;
+//    printf(">>%s<<\n",b);
+//  }
+//
+//  return 0;
+//}
+#endif
+
+/* ================================================================ */
+#if defined(HAVE_DYN_RL)
+#include <unistd.h>
+//#include <stdio.h>
+//#include <stdlib.h>
+//#include <sys/types.h>
+//#include <sys/file.h>
+//#include <sys/stat.h>
+//#include <sys/errno.h>
+//#include <dlfcn.h>
+#include "mod_raw.h"
+
+  typedef char **CPPFunction ();
+
+  char *(*fe_filename_completion_function)(); /* 3 */
+  char *(* fe_readline) ();                   /* 4 */
+  void (*fe_add_history) ();                  /* 5 */
+  char ** fe_rl_readline_name;                /* 6 */
+  char **fe_rl_line_buffer;                   /* 7 */
+  char **(*fe_completion_matches)();          /* 8 */
+  CPPFunction **fe_rl_attempted_completion_function; /* 9 */
+  FILE ** fe_rl_outstream;                    /* 10 */
+  int (*fe_write_history) ();                 /* 11 */
+  int (*fe_history_total_bytes) ();           /* 12 */
+  void (*fe_using_history) ();                /* 13 */
+  int (*fe_read_history) ();                  /* 14 */
+
+void * fe_rl_hdl=NULL;
+
+char *command_generator (char *text, int state);
+
+/* Attempt to complete on the contents of TEXT.  START and END show the
+*   region of TEXT that contains the word to complete.  We can use the
+*   entire line in case we want to do some simple parsing.  Return the
+*   array of matches, or NULL if there aren't any.
+*/
+char ** singular_completion (char *text, int start, int end)
+{
+  /* If this word is not in a string, then it may be a command
+     to complete.  Otherwise it may be the name of a file in the current
+     directory. */
+  char **m;
+  if ((*fe_rl_line_buffer)[start-1]=='"')
+    return (*fe_completion_matches) (text, *fe_filename_completion_function);
+  m=(*fe_completion_matches) (text, command_generator);
+  if (m==NULL)
+  {
+    m=(char **)malloc(2*sizeof(char*));
+    m[0]=(char *)malloc(end-start+2);
+    strncpy(m[0],text,end-start+1);
+    m[1]=NULL;
+  }
+  return m;
+}
+
+
+int fe_init_dyn_rl()
+{
+  int res=0;
+  loop
+  {
+    #if defined(HPUX_9) || defined(HPUX_10)
+    fe_rl_hdl=dynl_open("libreadline.sl");
+    if (fe_rl_hdl==NULL)
+      fe_rl_hdl=dynl_open("/lib/libreadline.sl");
+    if (fe_rl_hdl==NULL)
+      fe_rl_hdl=dynl_open("/usr/lib/libreadline.sl");
+    #else
+    fe_rl_hdl=dynl_open("libreadline.so");
+    if (fe_rl_hdl==NULL) fe_rl_hdl=dynl_open("libreadline.so.2");
+    if (fe_rl_hdl==NULL) fe_rl_hdl=dynl_open("libreadline.so.3");
+    if (fe_rl_hdl==NULL) fe_rl_hdl=dynl_open("libreadline.so.4");
+    #endif
+    if (fe_rl_hdl==NULL) { return 1;}
+
+    fe_filename_completion_function= 
+      dynl_sym(fe_rl_hdl, "filename_completion_function");
+    if (fe_filename_completion_function==NULL) { res=3; break; }
+    fe_readline=dynl_sym(fe_rl_hdl,"readline");
+    if (fe_readline==NULL) { res=4; break; }
+    fe_add_history=dynl_sym(fe_rl_hdl,"add_history");
+    if (fe_add_history==NULL) { res=5; break; }
+    fe_rl_readline_name=(char**)dynl_sym(fe_rl_hdl,"rl_readline_name");
+    if (fe_rl_readline_name==NULL) { res=6; break; }
+    fe_rl_line_buffer=(char**)dynl_sym(fe_rl_hdl,"rl_line_buffer");
+    if (fe_rl_line_buffer==NULL) { res=7; break; }
+    fe_completion_matches=dynl_sym(fe_rl_hdl,"completion_matches");
+    if (fe_completion_matches==NULL) { res=8; break; }
+    fe_rl_attempted_completion_function=
+      dynl_sym(fe_rl_hdl,"rl_attempted_completion_function");
+    if (fe_rl_attempted_completion_function==NULL) { res=9; break; }
+    fe_rl_outstream=(FILE**)dynl_sym(fe_rl_hdl,"rl_outstream");
+    if (fe_rl_outstream==NULL) { res=10; break; }
+    fe_write_history=dynl_sym(fe_rl_hdl,"write_history");
+    if (fe_write_history==NULL) { res=11; break; }
+    fe_history_total_bytes=dynl_sym(fe_rl_hdl,"history_total_bytes");
+    if (fe_history_total_bytes==NULL) { res=12; break; }
+    fe_using_history=dynl_sym(fe_rl_hdl,"using_history");
+    if (fe_using_history==NULL) { res=13; break; }
+    fe_read_history=dynl_sym(fe_rl_hdl,"read_history");
+    if (fe_read_history==NULL) { res=14; break; }
+    return 0;
+  }
+  dynl_close(fe_rl_hdl);
+  if (res==0)
+  {
+    char *p;
+    /* more init stuff: */
+    /* Allow conditional parsing of the ~/.inputrc file. */
+    (*fe_rl_readline_name) = "Singular";
+    /* Tell the completer that we want a crack first. */
+    (*fe_rl_attempted_completion_function) = (CPPFunction *)singular_completion;
+    /* try to read a history */
+    (*fe_using_history)();
+    p = getenv("SINGULARHIST");
+    if (p != NULL)
+    {
+      (*fe_read_history) (p);
+    }
+  }
+  return res;
+}
+#endif
+
+/* ===================================================================*/
+/* =          fe_reset_input_mode (all possibilities)               = */
+/* ===================================================================*/
+void fe_reset_input_mode ()
+{
+#if defined(HAVE_DYN_RL)
+  char *p = getenv("SINGULARHIST");
+  if ((p != NULL) && (fe_history_total_bytes != NULL))
+  {
+    if((*fe_history_total_bytes)()!=0)
+      (*fe_write_history) (p);
+  }
+#endif
+#if defined(HAVE_READLINE) && !defined(HAVE_FEREAD) && !defined(HAVE_DYN_RL)
+  char *p = getenv("SINGULARHIST");
+  if (p != NULL)
+  {
+    if(history_total_bytes()!=0)
+      write_history (p);
+  }
+#endif
+#if !defined(MSDOS) && defined(HAVE_FEREAD)
+  #ifndef HAVE_ATEXIT
+  fe_reset_fe(NULL,NULL);
+  #else
+  fe_reset_fe();
+  #endif
+#endif
+}
Index: kernel/ffields.cc
===================================================================
--- kernel/ffields.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/ffields.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,711 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: ffields.cc,v 1.1.1.1 2003-10-06 12:15:52 Singular Exp $ */
+/*
+* ABSTRACT: finite fields with a none-prime number of elements (via tables)
+*/
+
+#include <string.h>
+#include "mod2.h"
+#include <mylimits.h>
+#include "febase.h"
+#include "omalloc.h"
+#include "numbers.h"
+#include "ring.h"
+#include "ffields.h"
+
+int nfCharQ=0;  /* the number of elemts: q*/
+int nfM1;       /*representation of -1*/
+static int nfCharP=0;  /* the characteristic: p*/
+static int nfCharQ1=0; /* q-1 */
+CARDINAL *nfPlus1Table=NULL; /* the table i=log(z^i) -> log(z^i+1) */
+char * nfParameter;          /*  the name of the primitive element */
+/* the q's from the table 'fftable' */
+short fftable[]={
+    4,  8, 16, 32, 64, 128, 256, 512,1024,2048,4096,8192,16384,
+/*2^2 2^3 2^4 2^5 2^6  2^7  2^8  2^9 2^10 2^11 2^12 2^13  2^14*/
+    9, 27, 81,243,729,2187, 6561,19683,
+/*3^2 3^3 3^4 3^5 3^6  3^7  3^8   3^9*/
+   25,125,625,3125,15625,
+/*5^2 5^3 5^4 5^5  5^6*/
+   49,343,2401,16807,
+/*7^2 7^3  7^4 7^5*/
+   121,1331, 14641,
+/*11^2 11^3  11^4*/
+  169, 2197, 28561,
+/*13^2 13^3  13^4*/
+  289, 4913,
+/*17^2 17^3*/
+  361, 6859,
+/*19^2 19^3*/
+  529, 12167,
+/*23^2 23^3*/
+  841, 24389,
+/*29^2 29^3*/
+  961, 29791,
+/*31^2 31^3*/
+  1369,
+/*37^2*/
+  1681,
+/*41^2*/
+  1849,
+/*43^2*/
+  2209,
+/*47^2*/
+  2809,
+/*53^2*/
+  3481,
+/*59^2*/
+  3721,
+/*61^2*/
+  4489,
+/*67^2*/
+  5041,
+/*71^2*/
+  5329,
+/*73^2*/
+  6241,
+/*79^2*/
+  6889,
+/*83^2*/
+  7921,
+/*89^2*/
+  9409,
+/*97^2*/
+  10201,
+/*101^2*/
+  10609,
+/*103^2*/
+  11449,
+/*107^2*/
+  11881,
+/*109^2*/
+  12769,
+/*113^2*/
+  16129,
+/*127^2*/
+  17161,
+/*131^2*/
+  18769,
+/*137^2*/
+  19321,
+/*139^2*/
+  22201,
+/*149^2*/
+  22801,
+/*151^2*/
+  24649,
+/*157^2*/
+  26569,
+/*163^2*/
+  27889,
+/*167^2*/
+  29929,
+/*173^2*/
+  32041,
+/*179^2*/
+  32761,
+/*181^2*/
+  0 };
+
+/*1
+* numbers in GF(p^n):
+* let nfCharQ=q=nfCharP^n=p^n
+* GF(q)\{0} will be generated by powers of an element Z
+* Z^i will be represented by the int i, 1 by the int 0, 0 by the int q=nfChar
+*/
+
+#ifdef LDEBUG
+/*2
+* debugging: is a a valid representation of a number ?
+*/
+BOOLEAN nfDBTest (number a, char *f, int l)
+{
+  if (((int)a<0) || ((int)a>nfCharQ))
+  {
+    Print("wrong %d in %s:%d\n",(int)a,f,l);
+    return FALSE;
+  }
+  int i=0;
+  do
+  {
+    if (nfPlus1Table[i]>nfCharQ)
+    {
+      Print("wrong table %d=%d in %s:%d\n",i,nfPlus1Table[i],f,l);
+      return FALSE;
+    }
+    i++;
+  } while (i<nfCharQ);
+  return TRUE;
+}
+#define nfTest(N) nfDBTest(N,__FILE__,__LINE__)
+#endif
+
+/*2
+* k >= 0 ?
+*/
+BOOLEAN nfGreaterZero (number k)
+{
+#ifdef LDEBUG
+  nfTest(k);
+#endif
+  return !nfIsZero(k) && !nfIsMOne(k);
+}
+
+/*2
+* a*b
+*/
+number nfMult (number a,number b)
+{
+#ifdef LDEBUG
+  nfTest(a);
+  nfTest(b);
+#endif
+  if (((int)a == nfCharQ) || ((int)b == nfCharQ))
+    return (number)nfCharQ;
+  /*else*/
+  int i=(int)a+(int)b;
+  if (i>=nfCharQ1) i-=nfCharQ1;
+#ifdef LDEBUG
+  nfTest((number)i);
+#endif
+  return (number)i;
+}
+
+/*2
+* int -> number
+*/
+number nfInit (int i)
+{
+  // Hmm .. this is just to prevent initialization
+  // from nfInitChar to go into an infinite loop
+  if (i==0) return (number)nfCharQ;
+  while (i <  0)    i += nfCharP;
+  while (i >= nfCharP) i -= nfCharP;
+  if (i==0) return (number)nfCharQ;
+  int c=0;
+  while (i>1)
+  {
+    c=nfPlus1Table[c];
+    i--;
+  }
+#ifdef LDEBUG
+  nfTest((number)c);
+#endif
+  return (number)c;
+}
+
+/*
+* the generating element `z`
+*/
+number nfPar (int i)
+{
+  return (number)1;
+}
+
+/*2
+* the degree of the "alg. number"
+*/
+int nfParDeg(number n)
+{
+#ifdef LDEBUG
+  nfTest(n);
+#endif
+  if(nfCharQ == (int)n) return -1;
+  return (int)n;
+}
+
+/*2
+* number -> int
+*/
+int nfInt (number &n)
+{
+  return 0;
+}
+
+/*2
+* a + b
+*/
+number nfAdd (number a, number b)
+{
+/*4 z^a+z^b=z^b*(z^(a-b)+1), if a>=b; *
+*          =z^a*(z^(b-a)+1)  if a<b  */
+#ifdef LDEBUG
+  nfTest(a);
+  nfTest(b);
+#endif
+  if (nfCharQ == (int)a) return b;
+  if (nfCharQ == (int)b) return a;
+  int zb,zab,r;
+  if ((int)a >= (int)b)
+  {
+    zb = (int)b;
+    zab = (int)a-(int)b;
+  }
+  else
+  {
+    zb = (int)a;
+    zab = (int)b-(int)a;
+  }
+#ifdef LDEBUG
+  nfTest((number)zab);
+#endif
+  if (nfPlus1Table[zab]==nfCharQ) r=nfCharQ; /*if z^(a-b)+1 =0*/
+  else
+  {
+    r= zb+nfPlus1Table[zab];
+    if(r>=nfCharQ1) r-=nfCharQ1;
+  }
+#ifdef LDEBUG
+  nfTest((number)r);
+#endif
+  return (number)r;
+}
+
+/*2
+* a - b
+*/
+number nfSub (number a, number b)
+{
+  number mb = nfNeg(b);
+  return nfAdd(a,mb);
+}
+
+/*2
+* a == 0 ?
+*/
+BOOLEAN nfIsZero (number  a)
+{
+#ifdef LDEBUG
+  nfTest(a);
+#endif
+  return nfCharQ == (int)a;
+}
+
+/*2
+* a == 1 ?
+*/
+BOOLEAN nfIsOne (number a)
+{
+#ifdef LDEBUG
+  nfTest(a);
+#endif
+  return 0 == (int)a;
+}
+
+/*2
+* a == -1 ?
+*/
+BOOLEAN nfIsMOne (number a)
+{
+#ifdef LDEBUG
+  nfTest(a);
+#endif
+  if (0 == (int)a) return FALSE; /* special handling of char 2*/
+  return nfM1 == (int)a;
+}
+
+/*2
+* a / b
+*/
+number nfDiv (number a,number b)
+{
+#ifdef LDEBUG
+  nfTest(b);
+#endif
+  if ((int)b==nfCharQ)
+  {
+    WerrorS("div. by 0");
+    return (number)nfCharQ;
+  }
+#ifdef LDEBUG
+  nfTest(a);
+#endif
+  if ((int)a==nfCharQ)
+    return (number)nfCharQ;
+  /*else*/
+  int s = (int)a - (int)b;
+  if (s < 0)
+    s += nfCharQ1;
+#ifdef LDEBUG
+  nfTest((number)s);
+#endif
+  return (number)s;
+}
+
+/*2
+* 1 / c
+*/
+number  nfInvers (number c)
+{
+#ifdef LDEBUG
+  nfTest(c);
+#endif
+  if ((int)c==nfCharQ)
+  {
+    WerrorS("div. 1/0");
+    return (number)nfCharQ;
+  }
+#ifdef LDEBUG
+  nfTest(((number)(nfCharQ1-(int)c)));
+#endif
+  return (number)(nfCharQ1-(int)c);
+}
+
+/*2
+* -c
+*/
+number nfNeg (number c)
+{
+/*4 -z^c=z^c*(-1)=z^c*nfM1*/
+#ifdef LDEBUG
+  nfTest(c);
+#endif
+  if (nfCharQ == (int)c) return c;
+  int i=(int)c+nfM1;
+  if (i>=nfCharQ1) i-=nfCharQ1;
+#ifdef LDEBUG
+  nfTest((number)i);
+#endif
+  return (number)i;
+}
+
+/*2
+* a > b ?
+*/
+BOOLEAN nfGreater (number a,number b)
+{
+#ifdef LDEBUG
+  nfTest(a);
+  nfTest(b);
+#endif
+  return (int)a != (int)b;
+}
+
+/*2
+* a == b ?
+*/
+BOOLEAN nfEqual (number a,number b)
+{
+#ifdef LDEBUG
+  nfTest(a);
+  nfTest(b);
+#endif
+  return (int)a == (int)b;
+}
+
+/*2
+* write via StringAppend
+*/
+void nfWrite (number &a)
+{
+#ifdef LDEBUG
+  nfTest(a);
+#endif
+  if ((int)a==nfCharQ)  StringAppendS("0");
+  else if ((int)a==0)   StringAppendS("1");
+  else if (nfIsMOne(a))   StringAppendS("-1");
+  else
+  {
+    StringAppendS(nfParameter);
+    if ((int)a!=1)
+    {
+      if(currRing->ShortOut==0)  StringAppendS("^");
+      StringAppend("%d",(int)a);
+    }
+  }
+}
+
+/*2
+*
+*/
+char * nfName(number a)
+{
+#ifdef LDEBUG
+  nfTest(a);
+#endif
+  char *s;
+  if (((int)a==nfCharQ) || ((int)a==0)) return NULL;
+  else if ((int)a==1)
+  {
+    return omStrDup(nfParameter);
+  }
+  else
+  {
+    s=(char *)omAlloc(4+strlen(nfParameter));
+    sprintf(s,"%s%d",nfParameter,(int)a);
+  }
+  return s;
+}
+/*2
+* c ^ i with i>=0
+*/
+void nfPower (number a, int i, number * result)
+{
+#ifdef LDEBUG
+  nfTest(a);
+#endif
+  if (i==0)
+  {
+    //*result=nfInit(1);
+    *result = (number)0;
+  }
+  else if (i==1)
+  {
+    *result = a;
+  }
+  else
+  {
+    nfPower(a,i-1,result);
+    *result = nfMult(a,*result);
+  }
+#ifdef LDEBUG
+  nfTest(*result);
+#endif
+}
+
+/*4
+* read an integer (with reduction mod p)
+*/
+static char* nfEati(char *s, int *i)
+{
+  if (*s >= '0' && *s <= '9')
+  {
+    *i = 0;
+    do
+    {
+      *i *= 10;
+      *i += *s++ - '0';
+      if (*i > (MAX_INT_VAL / 10)) *i = *i % nfCharP;
+    }
+    while (*s >= '0' && *s <= '9');
+    if (*i >= nfCharP) *i = *i % nfCharP;
+  }
+  else *i = 1;
+  return s;
+}
+
+/*2
+* read a number
+*/
+char * nfRead (char *s, number *a)
+{
+  int i;
+  number z;
+  number n;
+
+  s = nfEati(s, &i);
+  z=nfInit(i);
+  *a=z;
+  if (*s == '/')
+  {
+    s++;
+    s = nfEati(s, &i);
+    n=nfInit(i);
+    *a = nfDiv(z,n);
+  }
+  if (strncmp(s,nfParameter,strlen(nfParameter))==0)
+  {
+    s+=strlen(nfParameter);
+    if ((*s >= '0') && (*s <= '9'))
+    {
+      s=eati(s,&i);
+      while (i>=nfCharQ1) i-=nfCharQ1;
+    }
+    else
+      i=1;
+    z=(number)i;
+    *a=nfMult(*a,z);
+  }
+#ifdef LDEBUG
+  nfTest(*a);
+#endif
+  return s;
+}
+
+#ifdef HAVE_FACTORY
+int gf_tab_numdigits62 ( int q );
+int convertback62 ( char * p, int n );
+#else
+static int gf_tab_numdigits62 ( int q )
+{
+    if ( q < 62 )          return 1;
+    else  if ( q < 62*62 ) return 2;
+    /*else*/               return 3;
+}
+
+static int convback62 ( char c )
+{
+    if ( c >= '0' && c <= '9' )
+        return int(c) - int('0');
+    else  if ( c >= 'A' && c <= 'Z' )
+        return int(c) - int('A') + 10;
+    else
+        return int(c) - int('a') + 36;
+}
+
+static int convertback62 ( char * p, int n )
+{
+    int r = 0;
+    for ( int j = 0; j < n; j++ )
+        r = r * 62 + convback62( p[j] );
+    return r;
+}
+#endif
+
+int nfMinPoly[16];
+
+void nfShowMipo()
+{
+  int i=nfMinPoly[0];
+  int j=0;
+  loop
+  {
+    j++;
+    if (nfMinPoly[j]!=0)
+      StringAppend("%d*%s^%d",nfMinPoly[j],nfParameter,i);
+    i--;
+    if(i<0) break;
+    if (nfMinPoly[j]!=0)
+      StringAppendS("+");
+  }
+}
+
+static void nfReadMipo(char *s)
+{
+  const char *l=strchr(s,';')+1;
+  char *n;
+  int i=strtol(l,&n,10);
+  l=n;
+  int j=1;
+  nfMinPoly[0]=i;
+  while(i>=0)
+  {
+    nfMinPoly[j]=strtol(l,&n,10);
+    if (l==n) break;
+    l=n;
+    j++;
+    i--;
+  }
+  if (i>=0)
+  {
+    WerrorS("error in reading minpoly from gftables");
+  }
+}
+
+/*2
+* init global variables from files 'gftables/%d'
+*/
+void nfSetChar(int c, char **param)
+{
+  //Print("GF(%d)\n",c);
+  nfParameter=param[0];
+  if ((c==nfCharQ)||(c==-nfCharQ))
+    /*this field is already set*/  return;
+  int i=0;
+  while ((fftable[i]!=c) && (fftable[i]!=0)) i++;
+  if (fftable[i]==0)
+    return;
+  if (nfCharQ > 1)
+  {
+    omFreeSize( (ADDRESS)nfPlus1Table,nfCharQ*sizeof(CARDINAL) );
+    nfPlus1Table=NULL;
+  }
+  if ((c>1) || (c<0))
+  {
+    if (c>1) nfCharQ = c;
+    else     nfCharQ = -c;
+    char buf[100];
+#ifdef macintosh
+    sprintf(buf,"gftables:%d",nfCharQ);
+#else
+    sprintf(buf,"gftables/%d",nfCharQ);
+#endif
+    FILE * fp = feFopen(buf,"r",NULL,TRUE);
+    if (fp==NULL)
+    {
+      return;
+    }
+    if(!fgets( buf, sizeof(buf), fp)) return;
+    if(strcmp(buf,"@@ factory GF(q) table @@\n")!=0)
+    {
+      goto err;
+    }
+    if(!fgets( buf, sizeof(buf), fp))
+    {
+      goto err;
+    }
+    int q;
+    sscanf(buf,"%d %d",&nfCharP,&q);
+    nfReadMipo(buf);
+    nfCharQ1=nfCharQ-1;
+    //Print("nfCharQ=%d,nfCharQ1=%d,mipo=>>%s<<\n",nfCharQ,nfCharQ1,buf);
+    nfPlus1Table= (CARDINAL *)omAlloc( (nfCharQ)*sizeof(CARDINAL) );
+    int digs = gf_tab_numdigits62( nfCharQ );
+    char * bufptr;
+    int i = 1;
+    int k;
+    while ( i < nfCharQ )
+    {
+      fgets( buf, sizeof(buf), fp);
+      //( strlen( buffer ) == (size_t)digs * 30, "illegal table" );
+      bufptr = buf;
+      k = 0;
+      while ( (i < nfCharQ) && (k < 30) )
+      {
+        nfPlus1Table[i] = convertback62( bufptr, digs );
+        if(nfPlus1Table[i]>nfCharQ)
+        {
+          Print("wrong entry %d: %d(%c%c%c)\n",i,nfPlus1Table[i],bufptr[0],bufptr[1],bufptr[2]);
+        }
+        bufptr += digs;
+        if (nfPlus1Table[i]==nfCharQ)
+        {
+          if(i==nfCharQ1)
+          {
+            nfM1=0;
+          }
+          else
+          {
+            nfM1=i;
+          }
+        }
+        i++; k++;
+      }
+    }
+    nfPlus1Table[0]=nfPlus1Table[nfCharQ1];
+  }
+  else
+    nfCharQ=0;
+#ifdef LDEBUG
+  nfTest((number)0);
+#endif
+  return;
+err:
+  Werror("illegal GF-table %d",nfCharQ);
+}
+
+/*2
+* map Z/p -> GF(p,n)
+*/
+number nfMapP(number c)
+{
+  return nfInit((int)c);
+}
+
+/*2
+* set map function nMap ... -> GF(p,n)
+*/
+nMapFunc nfSetMap(ring src, ring dst)
+{
+  if (rField_is_GF(src,nfCharQ))
+  {
+    return ndCopy;   /* GF(p,n) -> GF(p,n) */
+  }
+  if (rField_is_Zp(src,nfCharP))
+  {
+    return nfMapP;    /* Z/p -> GF(p,n) */
+  }
+  return NULL;     /* default */
+}
Index: kernel/ffields.h
===================================================================
--- kernel/ffields.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/ffields.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,42 @@
+#ifndef FFIELDS_H
+#define FFIELDS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: ffields.h,v 1.1.1.1 2003-10-06 12:15:52 Singular Exp $ */
+/*
+* ABSTRACT: finite fields with a none-prime number of elements (via tables)
+*/
+#include "structs.h"
+
+
+BOOLEAN nfGreaterZero (number k);
+number  nfMult        (number a, number b);
+number  nfInit        (int i);
+number  nfPar         (int i);
+int     nfParDeg      (number n);
+int     nfInt         (number &n);
+number  nfAdd         (number a, number b);
+number  nfSub         (number a, number b);
+void    nfPower       (number a, int i, number * result);
+BOOLEAN nfIsZero      (number a);
+BOOLEAN nfIsOne       (number a);
+BOOLEAN nfIsMOne      (number a);
+number  nfDiv         (number a, number b);
+number  nfNeg         (number c);
+number  nfInvers      (number c);
+BOOLEAN nfGreater     (number a, number b);
+BOOLEAN nfEqual       (number a, number b);
+void    nfWrite       (number &a);
+char *  nfRead        (char *s, number *a);
+#ifdef LDEBUG
+BOOLEAN nfDBTest      (number a, char *f, int l);
+#endif
+void    nfSetChar     (int c, char ** param);
+
+nMapFunc nfSetMap     (ring src, ring dst);
+char *  nfName        (number n);
+extern  int nfMinPoly[];
+void    nfShowMipo();
+#endif
+
Index: kernel/fglm.cc
===================================================================
--- kernel/fglm.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/fglm.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,441 @@
+// emacs edit mode for this file is -*- C++ -*-
+// $Id: fglm.cc,v 1.1.1.1 2003-10-06 12:15:52 Singular Exp $
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - The FGLM-Algorithm plus extension
+*   Calculate a reduced groebner basis for one ordering, given a
+*   reduced groebner basis for another ordering.
+*   In this file the input is checked. Furthermore we decide, if
+*   the input is 0-dimensional ( then fglmzero.cc is used ) or
+*   if the input is homogeneous ( then fglmhom.cc is used. Yet
+*   not implemented ).
+*   The extension (finduni) finds minimal univariate Polynomials
+*   lying in a 0-dimensional ideal.
+*/
+
+#include "mod2.h"
+
+#ifdef HAVE_FGLM
+#include "tok.h"
+#include "structs.h"
+#include "polys.h"
+#include "ideals.h"
+#include "ring.h"
+#include "ipid.h"
+#include "ipshell.h"
+#include "febase.h"
+#include "maps.h"
+#include "omalloc.h"
+#include "kstd1.h"
+#include "fglm.h"
+
+// internal Version: 1.18.1.6
+//     enumeration to handle the various errors to occour.
+enum FglmState{
+    FglmOk,
+    FglmHasOne,
+    FglmNoIdeal,
+    FglmNotReduced,
+    FglmNotZeroDim,
+    FglmIncompatibleRings,
+    // for fglmquot:
+    FglmPolyIsOne,
+    FglmPolyIsZero
+};
+
+// Has to be called, if currQuotient != NULL. ( i.e. qring-case )
+// Then a new ideal is build, consisting of the generators of sourceIdeal
+// and the generators of currQuotient, which are completely reduced by
+// the sourceIdeal. This means: If sourceIdeal is reduced, then the new
+// ideal will be reduced as well.
+// Assumes that currRing == sourceRing
+ideal fglmUpdatesource( const ideal sourceIdeal )
+{
+    int k, l, offset;
+    BOOLEAN found;
+    ideal newSource= idInit( IDELEMS( sourceIdeal ) + IDELEMS( currQuotient ), 1 );
+    for ( k= IDELEMS( sourceIdeal )-1; k >=0; k-- )
+        (newSource->m)[k]= pCopy( (sourceIdeal->m)[k] );
+    offset= IDELEMS( sourceIdeal );
+    for ( l= IDELEMS( currQuotient )-1; l >= 0; l-- ) {
+        if ( (currQuotient->m)[l] != NULL ) {
+            found= FALSE;
+            for ( k= IDELEMS( sourceIdeal )-1; (k >= 0) && (found == FALSE); k-- )
+                if ( pDivisibleBy( (sourceIdeal->m)[k], (currQuotient->m)[l] ) )
+                    found= TRUE;
+            if ( ! found ) {
+                (newSource->m)[offset]= pCopy( (currQuotient->m)[l] );
+                offset++;
+            }
+        }
+    }
+    idSkipZeroes( newSource );
+    return newSource;
+}
+
+// Has to be called, if currQuotient != NULL, i.e. in qring-case.
+// Gets rid of the elements of result which are contained in
+// currQuotient and skips Zeroes.
+// Assumes that currRing == destRing
+void
+fglmUpdateresult( ideal & result )
+{
+    int k, l;
+    BOOLEAN found;
+    for ( k= IDELEMS( result )-1; k >=0; k-- ) {
+        if ( (result->m)[k] != NULL ) {
+            found= FALSE;
+            for ( l= IDELEMS( currQuotient )-1; (l >= 0) && ( found == FALSE ); l-- )
+                if ( pDivisibleBy( (currQuotient->m)[l], (result->m)[k] ) )
+                    found= TRUE;
+            if ( found ) pDelete( & ((result->m)[k]) );
+        }
+    }
+    idSkipZeroes( result );
+}
+
+// Checks if the two rings sringHdl and dringHdl are compatible enough to
+// be used for the fglm. This means:
+//  1) Same Characteristic, 2) globalOrderings in both rings,
+//  3) Same number of variables, 4) same number of parameters
+//  5) variables in one ring are permutated variables of the other one
+//  6) parameters in one ring are permutated parameters of the other one
+//  7) either both rings are rings or both rings are qrings
+//  8) if they are qrings, the quotientIdeals of both must coincide.
+// vperm must be a vector of length pVariables+1, initialized by 0.
+// If both rings are compatible, it stores the permutation of the
+// variables if mapped from sringHdl to dringHdl.
+// if the rings are compatible, it returns FglmOk.
+// Should be called with currRing= IDRING( sringHdl );
+FglmState
+fglmConsistency( idhdl sringHdl, idhdl dringHdl, int * vperm )
+{
+    int k;
+    FglmState state= FglmOk;
+    ring dring = IDRING( dringHdl );
+    ring sring = IDRING( sringHdl );
+
+    if ( rChar(sring) != rChar(dring) ) {
+        WerrorS( "rings must have same characteristic" );
+        state= FglmIncompatibleRings;
+    }
+    if ( (sring->OrdSgn != 1) || (dring->OrdSgn != 1) ) {
+        WerrorS( "only works for global orderings" );
+        state= FglmIncompatibleRings;
+    }
+    if ( sring->N != dring->N )
+    {
+        WerrorS( "rings must have same number of variables" );
+        state= FglmIncompatibleRings;
+    }
+    if ( rPar(sring) != rPar(dring) )
+    {
+        WerrorS( "rings must have same number of parameters" );
+        state= FglmIncompatibleRings;
+    }
+    if ( state != FglmOk ) return state;
+    // now the rings have the same number of variables resp. parameters.
+    // check if the names of the variables resp. parameters do agree:
+    int nvar = sring->N;
+    int npar = rPar(sring);
+    int * pperm;
+    if ( npar > 0 )
+        pperm= (int *)omAlloc0( (npar+1)*sizeof( int ) );
+    else
+        pperm= NULL;
+    maFindPerm( sring->names, nvar, sring->parameter, npar,
+                dring->names, nvar, dring->parameter, npar, vperm, pperm,
+                dring->ch);
+    for ( k= nvar; (k > 0) && (state == FglmOk); k-- )
+        if ( vperm[k] <= 0 ) {
+            WerrorS( "variable names do not agree" );
+            state= FglmIncompatibleRings;
+        }
+    for ( k= npar-1; (k >= 0) && (state == FglmOk); k-- )
+        if ( pperm[k] >= 0 ) {
+            WerrorS( "paramater names do not agree" );
+            state= FglmIncompatibleRings;
+        }
+    if (pperm != NULL) // OB: ????
+      omFreeSize( (ADDRESS)pperm, (npar+1)*sizeof( int ) );
+    if ( state != FglmOk ) return state;
+    // check if both rings are qrings or not
+    if ( sring->qideal != NULL ) {
+        if ( dring->qideal == NULL ) {
+            Werror( "%s is a qring, current ring not", sringHdl->id );
+            return FglmIncompatibleRings;
+        }
+        // both rings are qrings, now check if both quotients define the same ideal.
+        // check if sring->qideal is contained in dring->qideal:
+        rSetHdl( dringHdl );
+        nMapFunc nMap=nSetMap( sring );
+        ideal sqind = idInit( IDELEMS( sring->qideal ), 1 );
+        for ( k= IDELEMS( sring->qideal )-1; k >= 0; k-- )
+          (sqind->m)[k]= pPermPoly( (sring->qideal->m)[k], vperm, sring, nMap);
+        ideal sqindred = kNF( dring->qideal, NULL, sqind );
+        if ( ! idIs0( sqindred ) ) {
+            WerrorS( "the quotients do not agree" );
+            state= FglmIncompatibleRings;
+        }
+        idDelete( & sqind );
+        idDelete( & sqindred );
+        rSetHdl( sringHdl );
+        if ( state != FglmOk ) return state;
+        // check if dring->qideal is contained in sring->qideal:
+        int * dsvperm = (int *)omAlloc0( (nvar+1)*sizeof( int ) );
+        maFindPerm( dring->names, nvar, NULL, 0, sring->names, nvar, NULL, 0,
+                    dsvperm, NULL, sring->ch);
+        nMap=nSetMap(dring);
+        ideal dqins = idInit( IDELEMS( dring->qideal ), 1 );
+        for ( k= IDELEMS( dring->qideal )-1; k >= 0; k-- )
+          (dqins->m)[k]=pPermPoly( (dring->qideal->m)[k], dsvperm, sring, nMap);
+        ideal dqinsred = kNF( sring->qideal, NULL, dqins );
+        if ( ! idIs0( dqinsred ) ) {
+            WerrorS( "the quotients do not agree" );
+            state= FglmIncompatibleRings;
+        }
+        idDelete( & dqins );
+        idDelete( & dqinsred );
+        omFreeSize( (ADDRESS)dsvperm, (nvar+1)*sizeof( int ) );
+        if ( state != FglmOk ) return state;
+    }
+    else {
+        if ( dring->qideal != NULL ) {
+            Werror( "current ring is a qring, %s not", sringHdl->id );
+            return FglmIncompatibleRings;
+        }
+    }
+    return FglmOk;
+}
+
+// Checks if the ideal "theIdeal" is zero-dimensional and minimal. It does
+//  not check, if it is reduced.
+// returns FglmOk if we can use theIdeal for CalculateFunctionals (this
+//                 function reports an error if theIdeal is not reduced,
+//                 so this need not to be tested here)
+//         FglmNotReduced if theIdeal is not minimal
+//         FglmNotZeroDim if it is not zero-dimensional
+//         FglmHasOne if 1 belongs to theIdeal
+FglmState
+fglmIdealcheck( const ideal theIdeal )
+{
+    FglmState state = FglmOk;
+    int power;
+    int k;
+    BOOLEAN * purePowers = (BOOLEAN *)omAlloc( pVariables*sizeof( BOOLEAN ) );
+    for ( k= pVariables-1; k >= 0; k-- )
+        purePowers[k]= FALSE;
+
+    for ( k= IDELEMS( theIdeal ) - 1; (state == FglmOk) && (k >= 0); k-- ) {
+        poly p = (theIdeal->m)[k];
+        if ( pIsConstant( p ) ) state= FglmHasOne;
+        else if ( (power= pIsPurePower( p )) > 0 ) {
+            fglmASSERT( 0 < power && power <= pVariables, "illegal power" );
+            if ( purePowers[power-1] == TRUE  ) state= FglmNotReduced;
+            else purePowers[power-1]= TRUE;
+        }
+        for ( int l = IDELEMS( theIdeal ) - 1; state == FglmOk && l >= 0; l-- )
+            if ( (k != l) && pDivisibleBy( p, (theIdeal->m)[l] ) )
+                state= FglmNotReduced;
+    }
+    if ( state == FglmOk ) {
+        for ( k= pVariables-1 ; (state == FglmOk) && (k >= 0); k-- )
+            if ( purePowers[k] == FALSE ) state= FglmNotZeroDim;
+    }
+    omFreeSize( (ADDRESS)purePowers, pVariables*sizeof( BOOLEAN ) );
+    return state;
+}
+
+// The main function for the fglm-Algorithm.
+// Checks the input-data, and calls fglmzero (see fglmzero.cc).
+// Returns the new groebnerbasis or 0 if an error occoured.
+BOOLEAN
+fglmProc( leftv result, leftv first, leftv second )
+{
+    FglmState state = FglmOk;
+
+    idhdl destRingHdl = currRingHdl;
+    ring destRing = currRing;
+    ideal destIdeal = NULL;
+    idhdl sourceRingHdl = (idhdl)first->data;
+    rSetHdl( sourceRingHdl );
+    ring sourceRing = currRing;
+
+    int * vperm = (int *)omAlloc0( (pVariables+1)*sizeof( int ) );
+    state= fglmConsistency( sourceRingHdl, destRingHdl, vperm );
+    omFreeSize( (ADDRESS)vperm, (pVariables+1)*sizeof(int) );
+
+    if ( state == FglmOk ) {
+        idhdl ih = currRing->idroot->get( second->Name(), myynest );
+        if ( (ih != NULL) && (IDTYP(ih)==IDEAL_CMD) ) {
+            ideal sourceIdeal;
+            if ( currQuotient != NULL )
+                sourceIdeal= fglmUpdatesource( IDIDEAL( ih ) );
+            else
+                sourceIdeal = IDIDEAL( ih );
+            state= fglmIdealcheck( sourceIdeal );
+            if ( state == FglmOk ) {
+                // Now the settings are compatible with FGLM
+                assumeStdFlag( (leftv)ih );
+                if ( fglmzero( sourceRingHdl, sourceIdeal, destRingHdl, destIdeal, FALSE, (currQuotient != NULL) ) == FALSE )
+                    state= FglmNotReduced;
+            }
+        } else state= FglmNoIdeal;
+    }
+    if ( currRingHdl != destRingHdl )
+        rSetHdl( destRingHdl );
+    switch (state) {
+        case FglmOk:
+            if ( currQuotient != NULL ) fglmUpdateresult( destIdeal );
+            break;
+        case FglmHasOne:
+            destIdeal= idInit(1,1);
+            (destIdeal->m)[0]= pOne();
+            state= FglmOk;
+            break;
+        case FglmIncompatibleRings:
+            Werror( "ring %s and current ring are incompatible", first->Name() );
+            destIdeal= idInit(0,0);
+            break;
+        case FglmNoIdeal:
+            Werror( "Can't find ideal %s in ring %s", second->Name(), first->Name() );
+            destIdeal= idInit(0,0);
+            break;
+        case FglmNotZeroDim:
+            Werror( "The ideal %s has to be 0-dimensional", second->Name() );
+            destIdeal= idInit(0,0);
+            break;
+        case FglmNotReduced:
+            Werror( "The ideal %s has to be reduced", second->Name() );
+            destIdeal= idInit(0,0);
+            break;
+        default:
+            destIdeal= idInit(1,1);
+    }
+
+    result->rtyp = IDEAL_CMD;
+    result->data= (void *)destIdeal;
+    setFlag( result, FLAG_STD );
+    return (state != FglmOk);
+}
+
+// fglmQuotProc: Calculate I:f with FGLM methods.
+// Checks the input-data, and calls fglmquot (see fglmzero.cc).
+// Returns the new groebnerbasis if I:f or 0 if an error occoured.
+BOOLEAN
+fglmQuotProc( leftv result, leftv first, leftv second )
+{
+    FglmState state = FglmOk;
+
+    //    STICKYPROT("quotstart\n");
+    ideal sourceIdeal = (ideal)first->Data();
+    poly quot = (poly)second->Data();
+    ideal destIdeal = NULL;
+
+    state = fglmIdealcheck( sourceIdeal );
+    if ( state == FglmOk ) {
+      if ( quot == NULL ) state= FglmPolyIsZero;
+      else if ( pIsConstant( quot ) ) state= FglmPolyIsOne;
+    }
+
+    if ( state == FglmOk ) {
+      assumeStdFlag( first );
+      if ( fglmquot( sourceIdeal, quot, destIdeal ) == FALSE )
+        state= FglmNotReduced;
+    }
+
+    switch (state) {
+        case FglmOk:
+            break;
+        case FglmHasOne:
+            destIdeal= idInit(1,1);
+            (destIdeal->m)[0]= pOne();
+            state= FglmOk;
+            break;
+        case FglmNotZeroDim:
+            Werror( "The ideal %s has to be 0-dimensional", first->Name() );
+            destIdeal= idInit(0,0);
+            break;
+        case FglmNotReduced:
+            Werror( "The poly %s has to be reduced", second->Name() );
+            destIdeal= idInit(0,0);
+            break;
+        case FglmPolyIsOne:
+	    int k;
+     	    destIdeal= idInit( IDELEMS(sourceIdeal), 1 );
+	    for ( k= IDELEMS( sourceIdeal )-1; k >=0; k-- )
+	      (destIdeal->m)[k]= pCopy( (sourceIdeal->m)[k] );
+            state= FglmOk;
+            break;
+        case FglmPolyIsZero:
+     	    destIdeal= idInit(1,1);
+            (destIdeal->m)[0]= pOne();
+            state= FglmOk;
+            break;
+        default:
+            destIdeal= idInit(1,1);
+    }
+
+    result->rtyp = IDEAL_CMD;
+    result->data= (void *)destIdeal;
+    setFlag( result, FLAG_STD );
+    // STICKYPROT("quotend\n");
+    return (state != FglmOk);
+} // fglmQuotProt
+
+// The main function for finduni().
+// Checks the input-data, and calls FindUnivariateWrapper (see fglmzero.cc).
+// Returns an ideal containing the univariate Polynomials or 0 if an error
+// has occoured.
+BOOLEAN
+findUniProc( leftv result, leftv first )
+{
+    ideal sourceIdeal;
+    ideal destIdeal = NULL;
+    FglmState state;
+
+    idhdl sourceIdealHdl = (idhdl)first->data;
+    sourceIdeal= IDIDEAL(sourceIdealHdl);
+
+    assumeStdFlag( first );
+    state= fglmIdealcheck( sourceIdeal );
+    if ( state == FglmOk ) {
+        if ( FindUnivariateWrapper( sourceIdeal, destIdeal ) == FALSE )
+            state = FglmNotReduced;
+    }
+    switch (state) {
+        case FglmOk:
+            break;
+        case FglmHasOne:
+            destIdeal= idInit(1,1);
+            (destIdeal->m)[0]= pOne();
+            state= FglmOk;
+            break;
+        case FglmNotZeroDim:
+            Werror( "The ideal %s has to be 0-dimensional", first->Name() );
+            destIdeal= idInit(0,0);
+            break;
+        case FglmNotReduced:
+            Werror( "The ideal %s has to be reduced", first->Name() );
+            destIdeal= idInit(0,0);
+            break;
+        default:
+            destIdeal= idInit(1,1);
+    }
+
+    result->rtyp = IDEAL_CMD;
+    result->data= (void *)destIdeal;
+
+    return FALSE;
+}
+#endif
+// ----------------------------------------------------------------------------
+// Local Variables: ***
+// compile-command: "make Singular" ***
+// page-delimiter: "^\\(
+\\|//!\\)" ***
+// fold-internal-margins: nil ***
+// End: ***
Index: kernel/fglm.h
===================================================================
--- kernel/fglm.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/fglm.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,121 @@
+// emacs edit mode for this file is -*- C++ -*-
+// $Id: fglm.h,v 1.1.1.1 2003-10-06 12:15:52 Singular Exp $
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - The FGLM-Algorithm
+*   The main header file for the fglm algorithm
+*   (See fglm.cc for details)
+*/
+
+#ifndef FGLM_H
+#define FGLM_H
+
+#ifdef HAVE_FGLM
+#include <factory.h>
+
+#include "polys.h"
+#include "fglmvec.h"
+
+#define PROT(msg)
+#define STICKYPROT(msg) if (BTEST1(OPT_PROT)) Print(msg)
+#define PROT2(msg,arg)
+#define STICKYPROT2(msg,arg) if (BTEST1(OPT_PROT)) Print(msg,arg)
+#define fglmASSERT(ignore1,ignore2)
+
+// internal Version: 1.10.1.4
+// Some data types needed by the fglm algorithm. claptmpl.cc has to know them.
+class fglmSelem
+{
+public:
+    int * divisors;
+    poly monom;
+    int numVars;
+    fglmSelem( poly p, int var );
+
+    void cleanup();
+    BOOLEAN isBasisOrEdge() const { return ( (divisors[0] == numVars) ? TRUE : FALSE ); }
+    void newDivisor( int var ) { divisors[ ++divisors[0] ]= var; }
+#ifndef NOSTREAMIO
+friend ostream & operator <<(ostream &, fglmSelem);
+#endif
+};
+#ifndef NOSTREAMIO
+inline ostream & operator <<(ostream & os, fglmSelem) { return os;};
+#endif
+
+class fglmDelem
+{
+public:
+    poly monom;
+    fglmVector v;
+    int insertions;
+    int var;
+    fglmDelem( poly & m, fglmVector mv, int v );
+
+    void cleanup();
+    BOOLEAN isBasisOrEdge() const { return ( (insertions == 0) ? TRUE : FALSE ); }
+    void newDivisor() { insertions--; }
+#ifndef NOSTREAMIO
+friend ostream & operator <<(ostream &, fglmDelem);
+#endif
+};
+#ifndef NOSTREAMIO
+inline ostream & operator <<(ostream & os, fglmDelem) { return os;};
+#endif
+
+// fglmzero(...):
+// The fglm algorithm for 0-dimensional ideals. ( fglmzero is defined in fglmzero.cc )
+// Calculates the reduced groebner basis of sourceIdeal in destRing.
+// The sourceIdeal has to be a reduced, 0-dimensional groebner basis in sourceRing.
+// Warning: There is no check, if the ideal is really 0-dimensional and minimal.
+// If it is minimal but not reduced, then it returns FALSE, otherwise TRUE.
+// Warning: There is no check, if the rings are compatible for fglm (see
+// fglm.cc for functions to check this)
+// if switchBack==TRUE, then the procedure sets the ring as currentRing which was
+// current when it was called ( When called there may be currRing != sourceRing ).
+// if switchBack==FALSE, then currRing==destRing at the end.
+// if deleteIdeal==TRUE then sourceIdeal is deleted (in any case, even if the
+// procedure fails)
+// if deleteIdeal==FALSE, then nothing happens to sourceIdeal
+BOOLEAN
+fglmzero( idhdl sourceRingHdl, ideal & sourceIdeal, idhdl destRingHdl, ideal & destideal, BOOLEAN switchBack = TRUE, BOOLEAN deleteIdeal = FALSE );
+
+BOOLEAN
+fglmquot( ideal sourceIdeal, poly quot, ideal & destIdeal );
+
+// fglmproc(...):
+// The procedure which has to be called from the interpreter for fglm.
+// first is the sourceRing, second is the given ideal in sourceRing.
+// Returns the groebnerbasis of the sourceIdeal in the currentRing.
+// Checks, if the ideal is really a reduced groebner basis of a
+// 0-dimensional Ideal. Returns TRUE if an error occoured.
+BOOLEAN
+fglmProc( leftv result, leftv first, leftv second );
+
+// fglmquotproc(...):
+// The procedure which has to be called from the interpreter for fglmquot.
+// first is the ideal I, second is the polynomial q. The polynomial must
+// be reduced with respect to I.
+// Returns the groebnerbasis of I:q in the currentRing.
+// Checks, if the ideal is really a reduced groebner basis of a
+// 0-dimensional Ideal and if q is really reduced.
+//  Returns TRUE if an error occoured.
+BOOLEAN
+fglmQuotProc( leftv result, leftv first, leftv second );
+
+// FindUnivariatePolys (test)
+BOOLEAN
+FindUnivariateWrapper( ideal source, ideal & dest );
+
+// wrapper for FindUnivariatePolys (test)
+BOOLEAN
+findUniProc( leftv result, leftv first);
+
+// homogeneous FGLM
+ideal
+fglmhomProc(leftv first, leftv second);
+#endif
+#endif
Index: kernel/fglmcomb.cc
===================================================================
--- kernel/fglmcomb.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/fglmcomb.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,567 @@
+// emacs edit mode for this file is -*- C++ -*-
+// $Id: fglmcomb.cc,v 1.1.1.1 2003-10-06 12:15:52 Singular Exp $
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT -
+*/
+
+#include "mod2.h"
+
+#ifdef HAVE_FGLM
+#include "structs.h"
+#include "polys.h"
+#include "ideals.h"
+#include "ring.h"
+#include "febase.h"
+#include "maps.h"
+#include "omalloc.h"
+#include "fglmvec.h"
+#include "fglmgauss.h"
+#include "kstd1.h"
+#define SI_DONT_HAVE_GLOBAL_VARS
+#include <factory.h>
+
+#include "fglm.h"
+#include <templates/ftmpl_list.h>
+
+#ifndef NOSTREAMIO
+#include <iostream.h>
+#endif
+// nur fuer debug-Ausgaben:
+static int
+pSize( poly p )
+{
+    int count = 0;
+    while ( p != NULL ) {
+        count+= nSize( pGetCoeff( p ) );
+        pIter( p );
+    }
+    return count;
+}
+
+static void
+fglmEliminateMonomials( poly * pptr, fglmVector & v, polyset monomials, int numMonoms )
+{
+    poly temp = *pptr;
+    poly pretemp = NULL;
+    int point = 0;
+    int state;
+
+    while ( (temp != NULL) && (point < numMonoms) ) {
+        state= pCmp( temp, monomials[point] );
+        if ( state == 0 ) {
+            // Eliminate this monomial
+            poly todelete;
+            if ( pretemp == NULL ) {
+                todelete = temp;
+                pIter( *pptr );
+                temp= *pptr;
+            }
+            else {
+                todelete= temp;
+                pIter( temp );
+                pretemp->next= temp;
+            }
+            pGetCoeff( todelete )= nNeg( pGetCoeff( todelete ) );
+            number newelem = nAdd( pGetCoeff( todelete ), v.getconstelem( point+1 ) );
+            v.setelem( point+1, newelem );
+            nDelete( & pGetCoeff( todelete ) );
+            pLmFree( todelete );
+            point++;
+        }
+        else if ( state < 0 )
+            point++;
+        else {
+            pretemp= temp;
+            pIter( temp );
+        }
+    }
+}
+
+static BOOLEAN
+fglmReductionStep( poly * pptr, ideal source, int * w )
+{
+// returns TRUE if the leading monomial was reduced
+    if ( *pptr == NULL ) return FALSE;
+    int k;
+    int best = 0;
+    for ( k= IDELEMS( source ) - 1; k >= 0; k-- ) {
+        if ( pDivisibleBy( (source->m)[k], *pptr ) ) {
+            if ( best == 0 ) {
+                best= k + 1;
+            }
+            else {
+                if ( w[k] < w[best-1] ) {
+                    best= k + 1;
+                }
+            }
+        }
+    }
+    if ( best > 0 ) {
+        // OwnSPoly
+        poly p2 = (source->m)[best-1];
+        int i, diff;
+
+        poly m = pOne();
+        for ( i= pVariables; i > 0; i-- ) {
+            diff= pGetExp( *pptr, i ) - pGetExp( p2, i );
+            pSetExp( m, i, diff );
+        }
+        pSetm( m );
+        number n1 = nCopy( pGetCoeff( *pptr ) );
+        number n2 = pGetCoeff( p2 );
+
+        p2= pCopy( p2 );
+        pDeleteLm(pptr);
+        pDeleteLm( & p2 );
+        p2= pMult( m, p2 );
+
+        number temp = nDiv( n1, n2 );
+        n_Normalize( temp, currRing );
+        nDelete( & n1 );
+        n1= temp;
+        n1= nNeg( n1 );
+        pMult_nn( p2, n1 );
+//         pNormalize( p2 );
+        nDelete( & n1 );
+        *pptr= pAdd( *pptr, p2 );
+    }
+    return ( (best > 0) );
+}
+
+static void
+fglmReduce( poly * pptr, fglmVector & v, polyset m, int numMonoms, ideal source, int * w )
+{
+    BOOLEAN reduced = FALSE;
+    reduced= fglmReductionStep( pptr, source, w );
+    while ( reduced == TRUE ) {
+        fglmEliminateMonomials( pptr, v, m, numMonoms );
+        reduced= fglmReductionStep( pptr, source, w );
+    }
+    STICKYPROT( "<" );
+    poly temp = * pptr;
+    if ( temp != NULL ) {
+        while ( pNext( temp ) != NULL ) {
+            STICKYPROT( ">" );
+            reduced= fglmReductionStep( & pNext( temp ), source, w );
+            while ( reduced == TRUE ) {
+                fglmEliminateMonomials( & pNext( temp ), v, m, numMonoms );
+                reduced= fglmReductionStep( & pNext( temp ), source, w );
+            }
+            if ( pNext( temp ) != NULL ) {
+                pIter( temp );
+            }
+        }
+    }
+}
+
+static poly
+fglmNewLinearCombination( ideal source, poly monset )
+{
+    polyset m = NULL;
+    polyset nf = NULL;
+    fglmVector * mv = NULL;
+
+    fglmVector * v = NULL;
+    polyset basis = NULL;
+    int basisSize = 0;
+    int basisBS = 16;
+    int basisMax = basisBS;
+
+    int * weights = NULL;
+    int * lengthes = NULL;
+    int * order = NULL;
+
+    int numMonoms = 0;
+    int k;
+
+    // get number of monoms
+    numMonoms= pLength( monset );
+    STICKYPROT2( "%i monoms\n", numMonoms );
+
+    // Allcoate Memory and initialize sets
+    m= (polyset)omAlloc( numMonoms * sizeof( poly ) );
+    poly temp= monset;
+    for ( k= 0; k < numMonoms; k++ ) {
+//         m[k]= pOne();
+//         pSetExpV( m[k], temp->exp );
+//         pSetm( m[k] );
+        m[k]=pLmInit(temp);
+        pSetCoeff( m[k], nInit(1) );
+        pIter( temp );
+    }
+
+    nf= (polyset)omAlloc( numMonoms * sizeof( poly ) );
+
+#ifndef HAVE_EXPLICIT_CONSTR
+    mv= new fglmVector[ numMonoms ];
+#else
+    mv= (fglmVector *)omAlloc( numMonoms * sizeof( fglmVector ) );
+#endif
+
+#ifndef HAVE_EXPLICIT_CONSTR
+    v= new fglmVector[ numMonoms ];
+#else
+    v= (fglmVector *)omAlloc( numMonoms * sizeof( fglmVector ) );
+#endif
+
+    basisMax= basisBS;
+    basis= (polyset)omAlloc( basisMax * sizeof( poly ) );
+
+    weights= (int *)omAlloc( IDELEMS( source ) * sizeof( int ) );
+    STICKYPROT( "weights: " );
+    for ( k= 0; k < IDELEMS( source ); k++ ) {
+        poly temp= (source->m)[k];
+        int w = 0;
+        while ( temp != NULL ) {
+            w+= nSize( pGetCoeff( temp ) );
+            pIter( temp );
+        }
+        weights[k]= w;
+        STICKYPROT2( "%i ", w );
+    }
+    STICKYPROT( "\n" );
+    lengthes= (int *)omAlloc( numMonoms * sizeof( int ) );
+    order= (int *)omAlloc( numMonoms * sizeof( int ) );
+
+    // calculate the NormalForm in a special way
+    for ( k= 0; k < numMonoms; k++ )
+    {
+        STICKYPROT( "#" );
+        poly current = pCopy( m[k] );
+        fglmVector currV( numMonoms, k+1 );
+
+        fglmReduce( & current, currV, m, numMonoms, source, weights );
+        poly temp = current;
+        int b;
+        while ( temp != NULL )
+        {
+            BOOLEAN found = FALSE;
+            for ( b= 0; (b < basisSize) && (found == FALSE); b++ )
+            {
+                if ( pLmEqual( temp, basis[b] ) )
+                {
+                    found= TRUE;
+                }
+            }
+            if ( found == FALSE )
+            {
+                if ( basisSize == basisMax )
+                {
+                    // Expand the basis
+                    basis= (polyset)omReallocSize( basis, basisMax * sizeof( poly ), (basisMax + basisBS ) * sizeof( poly ) );
+                    basisMax+= basisBS;
+                }
+//                 basis[basisSize]= pOne();
+//                 pSetExpV( basis[basisSize], temp->exp );
+//                 pSetm( basis[basisSize] );
+                basis[basisSize]=pLmInit(temp);
+                pSetCoeff( basis[basisSize], nInit(1) );
+                basisSize++;
+            }
+            pIter( temp );
+        }
+        nf[k]= current;
+#ifndef HAVE_EXPLICIT_CONSTR
+        mv[k].mac_constr( currV );
+#else
+        mv[k].fglmVector( currV );
+#endif
+        STICKYPROT( "\n" );
+    }
+    // get the vector representation
+    for ( k= 0; k < numMonoms; k++ ) {
+        STICKYPROT( "." );
+
+#ifndef HAVE_EXPLICIT_CONSTR
+        v[k].mac_constr_i( basisSize );
+#else
+        v[k].fglmVector( basisSize );
+#endif
+        poly mon= nf[k];
+        while ( mon != NULL ) {
+            BOOLEAN found = FALSE;
+            int b= 0;
+            while ( found == FALSE ) {
+                if ( pLmEqual( mon, basis[b] ) ) {
+                    found= TRUE;
+                }
+                else {
+                    b++;
+                }
+            }
+            number coeff = nCopy( pGetCoeff( mon ) );
+            v[k].setelem( b+1, coeff );
+            pIter( mon );
+        }
+        pDelete( nf + k );
+    }
+    // Free Memory not needed anymore
+    omFreeSize( (ADDRESS)nf, numMonoms * sizeof( poly ) );
+    omFreeSize( (ADDRESS)weights, IDELEMS( source ) * sizeof( int ) );
+
+    STICKYPROT2( "\nbasis size: %i\n", basisSize );
+    STICKYPROT( "(clear basis" );
+    for ( k= 0; k < basisSize; k++ )
+        pDelete( basis + k );
+    STICKYPROT( ")\n" );
+    // gauss reduce
+    gaussReducer gauss( basisSize );
+    BOOLEAN isZero = FALSE;
+    fglmVector p;
+
+    STICKYPROT( "sizes: " );
+    for ( k= 0; k < numMonoms; k++ ) {
+        lengthes[k]= v[k].numNonZeroElems();
+        STICKYPROT2( "%i ", lengthes[k] );
+    }
+    STICKYPROT( "\n" );
+
+    int act = 0;
+    while ( (isZero == FALSE) && (act < numMonoms) ) {
+        int best = 0;
+        for ( k= numMonoms - 1; k >= 0; k-- ) {
+            if ( lengthes[k] > 0 ) {
+                if ( best == 0 ) {
+                    best= k+1;
+                }
+                else {
+                    if ( lengthes[k] < lengthes[best-1] ) {
+                        best= k+1;
+                    }
+                }
+            }
+        }
+        lengthes[best-1]= 0;
+        order[act]= best-1;
+        STICKYPROT2( " (%i) ", best );
+        if ( ( isZero= gauss.reduce( v[best-1] )) == TRUE ) {
+            p= gauss.getDependence();
+        }
+        else {
+            STICKYPROT( "+" );
+            gauss.store();
+            act++;
+        }
+#ifndef HAVE_EXPLICIT_CONSTR
+        v[best-1].clearelems();
+#else
+        v[best-1].~fglmVector();
+#endif
+    }
+    poly result = NULL;
+    if ( isZero == TRUE ) {
+        number gcd = p.gcd();
+        if ( ! nIsZero( gcd ) && ! ( nIsOne( gcd ) ) ) {
+            p/= gcd;
+        }
+        nDelete( & gcd );
+        fglmVector temp( numMonoms );
+        for ( k= 0; k < p.size(); k++ ) {
+            if ( ! p.elemIsZero( k+1 ) ) {
+                temp+= p.getconstelem( k+1 ) * mv[order[k]];
+            }
+        }
+        number denom = temp.clearDenom();
+        nDelete( & denom );
+        gcd = temp.gcd();
+        if ( ! nIsZero( gcd ) && ! nIsOne( gcd ) ) {
+            temp/= gcd;
+        }
+        nDelete( & gcd );
+
+        poly sum = NULL;
+        for ( k= 1; k <= numMonoms; k++ ) {
+            if ( ! temp.elemIsZero( k ) ) {
+                if ( result == NULL ) {
+                    result= pCopy( m[k-1] );
+                    sum= result;
+                }
+                else {
+                    sum->next= pCopy( m[k-1] );
+                    pIter( sum );
+                }
+                pSetCoeff( sum, nCopy( temp.getconstelem( k ) ) );
+            }
+        }
+        pContent( result );
+        if ( ! nGreaterZero( pGetCoeff( result ) ) ) result= pNeg( result );
+    }
+    // Free Memory
+    omFreeSize( (ADDRESS)lengthes, numMonoms * sizeof( int ) );
+    omFreeSize( (ADDRESS)order, numMonoms * sizeof( int ) );
+//     for ( k= 0; k < numMonoms; k++ )
+//         v[k].~fglmVector();
+#ifndef HAVE_EXPLICIT_CONSTR
+    delete [] v;
+#else
+    omFreeSize( (ADDRESS)v, numMonoms * sizeof( fglmVector ) );
+#endif
+
+    for ( k= 0; k < basisSize; k++ )
+        pDelete( basis + k );
+    omFreeSize( (ADDRESS)basis, basisMax * sizeof( poly ) );
+
+#ifndef HAVE_EXPLICIT_CONSTR
+    delete [] mv;
+#else
+    for ( k= 0; k < numMonoms; k++ )
+        mv[k].~fglmVector();
+    omFreeSize( (ADDRESS)mv, numMonoms * sizeof( fglmVector ) );
+#endif
+
+    for ( k= 0; k < numMonoms; k++ )
+        pDelete( m + k );
+    omFreeSize( (ADDRESS)m, numMonoms * sizeof( poly ) );
+
+    STICKYPROT( "\n" );
+    return result;
+}
+
+
+static poly
+fglmLinearCombination( ideal source, poly monset )
+{
+    int k;
+    poly temp;
+
+    polyset m;
+    polyset nf;
+    fglmVector * v;
+
+    polyset basis;
+    int basisSize = 0;
+    int basisBS = 16;
+    int basisMax;
+    // get number of monomials in monset
+    int numMonoms = 0;
+    temp = monset;
+    while ( temp != NULL ) {
+        numMonoms++;
+        pIter( temp );
+    }
+    // Allocate Memory
+    m= (polyset)omAlloc( numMonoms * sizeof( poly ) );
+    nf= (polyset)omAlloc( numMonoms * sizeof( poly ) );
+    // Warning: The fglmVectors in v are yet not initialized
+    v= (fglmVector *)omAlloc( numMonoms * sizeof( fglmVector ) );
+    basisMax= basisBS;
+    basis= (polyset)omAlloc( basisMax * sizeof( poly ) );
+
+    // get the NormalForm and the basis monomials
+    temp= monset;
+    for ( k= 0; k < numMonoms; k++ ) {
+        poly mon= pHead( temp );
+        if ( ! nIsOne( pGetCoeff( mon ) ) ) {
+            nDelete( & pGetCoeff( mon ) );
+            pSetCoeff( mon, nInit( 1 ) );
+        }
+        STICKYPROT( "(" );
+        nf[k]= kNF( source, currRing->qideal, mon );
+        STICKYPROT( ")" );
+
+        // search through basis
+        STICKYPROT( "[" );
+        poly sm = nf[k];
+        while ( sm != NULL ) {
+            BOOLEAN found = FALSE;
+            int b;
+            for ( b= 0; (b < basisSize) && (found == FALSE); b++ )
+                if ( pLmEqual( sm, basis[b] ) ) found= TRUE;
+            if ( found == FALSE ) {
+                // Expand the basis
+                if ( basisSize == basisMax ) {
+                    basis= (polyset)omReallocSize( basis, basisMax * sizeof( poly ), (basisMax + basisBS ) * sizeof( poly ) );
+                    basisMax+= basisBS;
+                }
+                basis[basisSize]= pHead( sm );
+                nDelete( & pGetCoeff( basis[basisSize] ) );
+                pSetCoeff( basis[basisSize], nInit( 1 ) );
+                basisSize++;
+            }
+            pIter( sm );
+        }
+        STICKYPROT( "]" );
+        m[k]= mon;
+        pIter( temp );
+    }
+    // get the vector representation
+    STICKYPROT2( "(%i)", basisSize );
+    for ( k= 0; k < numMonoms; k++ ) {
+#ifndef HAVE_EXPLICIT_CONSTR
+        v[k].mac_constr_i( basisSize );
+#else
+        v[k].fglmVector( basisSize );
+#endif
+        STICKYPROT( "(+" );
+        poly mon= nf[k];
+        while ( mon != NULL ) {
+            BOOLEAN found = FALSE;
+            int b= 0;
+            while ( found == FALSE ) {
+                if ( pLmEqual( mon, basis[b] ) )
+                    found= TRUE;
+                else
+                    b++;
+            }
+            number coeff = nCopy( pGetCoeff( mon ) );
+            v[k].setelem( b+1, coeff );
+            pIter( mon );
+        }
+        STICKYPROT( ")" );
+    }
+    // gauss reduce
+    gaussReducer gauss( basisSize );
+    BOOLEAN isZero = FALSE;
+    fglmVector p;
+    for ( k= 0; (k < numMonoms) && (isZero == FALSE); k++ ) {
+        STICKYPROT( "(-" );
+        if ( ( isZero= gauss.reduce( v[k] )) == TRUE )
+            p= gauss.getDependence();
+        else
+            gauss.store();
+        STICKYPROT( ")" );
+    }
+    poly comb = NULL;
+    if ( isZero == TRUE ) {
+        number gcd = p.gcd();
+        if ( ! nIsZero( gcd ) && ! ( nIsOne( gcd ) ) )
+            p/= gcd;
+        nDelete( & gcd );
+        for ( k= 1; k <= p.size(); k++ ) {
+            if ( ! p.elemIsZero( k ) ) {
+                poly temp = pCopy( m[k-1] );
+                pSetCoeff( temp, nCopy( p.getconstelem( k ) ) );
+                comb= pAdd( comb, temp );
+            }
+        }
+        if ( ! nGreaterZero( pGetCoeff( comb ) ) ) comb= pNeg( comb );
+    }
+
+    // Free Memory
+    for ( k= 0; k < numMonoms; k++ ) {
+        pDelete( m + k );
+        pDelete( nf + k );
+    }
+    omFreeSize( (ADDRESS)m, numMonoms * sizeof( poly ) );
+    omFreeSize( (ADDRESS)nf, numMonoms * sizeof( poly ) );
+    // Warning: At this point all Vectors in v have to be initialized
+    for ( k= numMonoms - 1; k >= 0; k-- ) v[k].~fglmVector();
+    omFreeSize( (ADDRESS)v, numMonoms * sizeof( fglmVector ) );
+    for ( k= 0; k < basisSize; k++ )
+        pDelete( basis + k );
+    omFreeSize( (ADDRESS)basis, basisMax * sizeof( poly ) );
+    STICKYPROT( "\n" );
+    return comb;
+}
+
+#endif
+// Local Variables: ***
+// compile-command: "make Singular" ***
+// page-delimiter: "^\\(
+\\|//!\\)" ***
+// fold-internal-margins: nil ***
+// End: ***
Index: kernel/fglmgauss.cc
===================================================================
--- kernel/fglmgauss.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/fglmgauss.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,211 @@
+// emacs edit mode for this file is -*- C++ -*-
+// $Id: fglmgauss.cc,v 1.1.1.1 2003-10-06 12:15:52 Singular Exp $
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - class gaussReducer. Used in fglmzero.cc and fglmhom.cc
+*  to find linear dependecies of fglmVectors.
+*/
+
+#include "mod2.h"
+
+#ifdef  HAVE_FACTORY
+#include "structs.h"
+#include "numbers.h"
+#include "omalloc.h"
+
+#include "fglmvec.h"
+#include "fglmgauss.h"
+
+class gaussElem
+{
+public:
+    fglmVector v;
+    fglmVector p;
+    number pdenom;
+    number fac;
+    gaussElem( const fglmVector newv, const fglmVector newp, number & newpdenom, number & newfac ) : v( newv ), p( newp ), pdenom( newpdenom ), fac( newfac )
+    {
+        newpdenom= NULL;
+        newfac= NULL;
+    }
+
+#ifndef HAVE_EXPLICIT_CONSTR
+  gaussElem() : v(), p(), pdenom(NULL), fac(NULL) {}
+
+  void mac_gaussElem( const fglmVector newv, const fglmVector newp, number & newpdenom, number & newfac )
+    {
+    v= newv;
+    p= newp;
+    pdenom=newpdenom;
+    fac=newfac;
+        newpdenom= NULL;
+        newfac= NULL;
+    }
+#endif
+
+    ~gaussElem()
+    {
+        nDelete( & pdenom );
+        nDelete( & fac );
+    }
+};
+
+gaussReducer::gaussReducer( int dimen )
+{
+    int k;
+    size= 0;
+    max= dimen;
+#ifndef HAVE_EXPLICIT_CONSTR
+    elems= new gaussElem[ max+1 ];
+#else
+    elems= (gaussElem *)omAlloc( (max+1)*sizeof( gaussElem ) );
+#endif
+    isPivot= (BOOLEAN *)omAlloc( (max+1)*sizeof( BOOLEAN ) );
+    for ( k= max; k > 0; k-- )
+            isPivot[k]= FALSE;
+    perm= (int *)omAlloc( (max+1)*sizeof( int ) );
+}
+
+gaussReducer::~gaussReducer()
+{
+    int k;
+
+#ifndef HAVE_EXPLICIT_CONSTR
+    delete [] elems;
+#else
+    for ( k= size; k > 0; k-- )
+        elems[k].~gaussElem();
+    omFreeSize( (ADDRESS)elems, (max+1)*sizeof( gaussElem ) );
+#endif
+
+    omFreeSize( (ADDRESS)isPivot, (max+1)*sizeof( BOOLEAN ) );
+    omFreeSize( (ADDRESS)perm, (max+1)*sizeof( int ) );
+}
+
+BOOLEAN
+gaussReducer::reduce( fglmVector thev )
+{
+    number fac1, fac2;
+    number temp;
+    // Hier ueberlegen, ob thev als referenz, oder wie wann was kopiert usw.
+    v= thev;
+    p= fglmVector( size + 1, size + 1 );
+    // fglmASSERT( pdenom == NULL );
+    pdenom= nInit( 1 );
+    number vdenom = v.clearDenom();
+    if ( ! nIsOne( vdenom ) && ! nIsZero( vdenom ) ) {
+        p.setelem( p.size(), vdenom );
+    }
+    else {
+        nDelete( & vdenom );
+    }
+    number gcd = v.gcd();
+    if ( ! nIsOne( gcd ) && ! nIsZero( gcd ) ) {
+        v /= gcd;
+        number temp= nMult( pdenom, gcd );
+        nDelete( & pdenom );
+        pdenom= temp;
+    }
+    nDelete( & gcd );
+
+    int k;
+    for ( k= 1; k <= size; k++ ) {
+        if ( ! v.elemIsZero( perm[k] ) ) {
+            fac1= elems[k].fac;
+            fac2= nCopy( v.getconstelem( perm[k] ) );
+            v.nihilate( fac1, fac2, elems[k].v );
+            fac1= nMult( fac1, elems[k].pdenom );
+            temp= nMult( fac2, pdenom );
+            nDelete( & fac2 );
+            fac2= temp;
+            p.nihilate( fac1, fac2, elems[k].p );
+            temp= nMult( pdenom, elems[k].pdenom );
+            nDelete( & pdenom );
+            pdenom= temp;
+
+            nDelete( & fac1 );
+            nDelete( & fac2 );
+            number gcd = v.gcd();
+            if ( ! nIsOne( gcd ) && ! nIsZero( gcd ) ) {
+                v/= gcd;
+                number temp = nMult( pdenom, gcd );
+                nDelete( & pdenom );
+                pdenom= temp;
+            }
+            nDelete( & gcd );
+            gcd= p.gcd();
+            temp= nGcd( pdenom, gcd, currRing );
+            nDelete( & gcd );
+            gcd= temp;
+            if ( ! nIsZero( gcd ) && ! nIsOne( gcd ) ) {
+                p/= gcd;
+                temp= nDiv( pdenom, gcd );
+                nDelete( & pdenom );
+                pdenom= temp;
+                nNormalize( pdenom );
+            }
+            nDelete( & gcd );
+        }
+    }
+    return ( v.isZero() );
+}
+
+void
+gaussReducer::store()
+{
+    // fglmASSERT( size < max );
+    number fac;
+    // find the pivot-element in v:
+
+    size++;
+    int k= 1;
+    while ( nIsZero(v.getconstelem(k)) || isPivot[k] ) {
+        k++;
+    }
+    // fglmASSERT( k <= dimen, "Error(1) in fglmDdata::pivot-search");
+    number pivot= v.getconstelem( k );
+    int pivotcol = k;
+    k++;
+    while ( k <= max ) {
+        if ( ! nIsZero( v.getconstelem(k) ) && ! isPivot[k] ) {
+            if ( nGreater( v.getconstelem( k ), pivot ) ) {
+                pivot= v.getconstelem( k );
+                pivotcol= k;
+            }
+        }
+        k++;
+    }
+    // fglmASSERT( ! nIsZero( pivot ), "Error(2) fglmDdata::Pivotelement ist Null" );
+    isPivot[ pivotcol ]= TRUE;
+    perm[size]= pivotcol;
+
+    pivot= nCopy( v.getconstelem( pivotcol ) );
+#ifndef HAVE_EXPLICIT_CONSTR
+    elems[size].mac_gaussElem( v, p, pdenom, pivot );
+#else
+    elems[size].gaussElem( v, p, pdenom, pivot );
+#endif
+}
+
+fglmVector
+gaussReducer::getDependence()
+{
+    nDelete( & pdenom );
+    // hier kann p noch gekuerzt werden, je nach Charakteristik
+    fglmVector result = p;
+    p= fglmVector();
+    return ( result );
+}
+// ================================================================================
+
+// ----------------------------------------------------------------------------
+// Local Variables: ***
+// compile-command: "make Singular" ***
+// page-delimiter: "^\\(
+\\|//!\\)" ***
+// fold-internal-margins: nil ***
+// End: ***
+#endif // HAVE_FACTORY
Index: kernel/fglmgauss.h
===================================================================
--- kernel/fglmgauss.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/fglmgauss.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,48 @@
+// emacs edit mode for this file is -*- C++ -*-
+// $Id: fglmgauss.h,v 1.1.1.1 2003-10-06 12:15:52 Singular Exp $
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - header file for the gauss - reducer
+*            (used by fglm)
+*/
+#ifndef FGLMGAUSS_H
+#define FGLMGAUSS_H
+
+#include "structs.h"
+#include "fglmvec.h"
+
+class gaussElem;
+
+class gaussReducer
+{
+private:
+    gaussElem * elems;
+    BOOLEAN * isPivot;
+    int * perm;
+    fglmVector v;
+    fglmVector p;
+    number pdenom;
+    int size;
+    int max;
+public:
+    gaussReducer( int dimen );
+    ~gaussReducer();
+
+    // reduce returns TRUE, if v reduces to 0, FALSE otherwise;
+    BOOLEAN reduce( fglmVector v );
+
+    // if a vector does not reduce to zero, then it can be stored as a new gauss
+    // vector.
+    // Has to be called after reduce!
+    void store();
+
+    // if a vector reduces to zero, then one can get the corresponding fglmVector
+    // of the linear dependence
+    // Has to be called after reduce!
+    fglmVector getDependence();
+};
+
+#endif
Index: kernel/fglmhom.cc
===================================================================
--- kernel/fglmhom.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/fglmhom.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,453 @@
+// emacs edit mode for this file is -*- C++ -*-
+// $Id: fglmhom.cc,v 1.1.1.1 2003-10-06 12:15:53 Singular Exp $
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - The FGLM-Algorithm extended for homogeneous ideals.
+*   Calculates via the hilbert-function a groebner basis.
+*/
+
+
+#include "mod2.h"
+#ifdef HAVE_FGLM_HOM
+#ifndef NOSTREAMIO
+#include <iostream.h>
+#endif
+#include "tok.h"
+#include "structs.h"
+#include "subexpr.h"
+#include "polys.h"
+#include "ideals.h"
+#include "ring.h"
+#include "ipid.h"
+#include "ipshell.h"
+#include "febase.h"
+#include "maps.h"
+#include "omalloc.h"
+#include "fglm.h"
+#include "fglmvec.h"
+#include "fglmgauss.h"
+#include "intvec.h"
+#include "kstd1.h"
+#include "stairc.h"  // -> hHStdSeries, hFirstSeries usw.
+#include <templates/ftmpl_list.h>
+
+// obachman: Got rid off those "redefiende messages by includeing fglm.h
+#include "fglm.h"
+#if 0
+#define PROT(msg) if (BTEST1(OPT_PROT)) Print(msg)
+#define STICKYPROT(msg) if (BTEST1(OPT_PROT)) Print(msg)
+#define PROT2(msg,arg) if (BTEST1(OPT_PROT)) Print(msg,arg)
+#define STICKYPROT2(msg,arg) if (BTEST1(OPT_PROT)) Print(msg,arg)
+#define fglmASSERT(ignore1,ignore2)
+#endif
+
+struct doublepoly
+{
+    poly sm;
+    poly dm;
+};
+
+class homogElem
+{
+public:
+    doublepoly mon;
+    fglmVector v;
+    fglmVector dv;
+    int basis;
+    int destbasis;
+    BOOLEAN inDest;
+    homogElem() : v(), dv(), basis(0), destbasis(0), inDest(FALSE) {}
+    homogElem( poly m, int b, BOOLEAN ind ) :
+        basis(b), inDest(ind)
+    {
+        mon.dm= m;
+        mon.sm= NULL;
+    }
+#ifndef HAVE_EXPLICIT_CONSTR
+    void initialize( poly m, int b, BOOLEAN ind )
+    {
+	basis = b;
+	inDest = ind;
+	mon.dm = m;
+	mon.sm = NULL;
+    }
+    void initialize( const homogElem h )
+    {
+	basis = h.basis;
+	inDest = h.inDest;
+	mon.dm = h.mon.dm;
+	mon.sm = h.mon.sm;
+    }
+#endif
+};
+
+struct homogData
+{
+    ideal sourceIdeal;
+    doublepoly * sourceHeads;
+    int numSourceHeads;
+    ideal destIdeal;
+    int numDestPolys;
+    homogElem * monlist;
+    int monlistmax;
+    int monlistblock;
+    int numMonoms;
+    int basisSize;
+    int overall;  // nur zum testen.
+    int numberofdestbasismonoms;
+//     homogData() : sourceHeads(NULL), numSourceHeads(0), monlist(NULL),
+//         numMonoms(0), basisSize(0) {}
+};
+
+int
+hfglmNextdegree( intvec * source, ideal current, int & deg )
+{
+    int numelems;
+    intvec * newhilb = hHstdSeries( current, NULL, currQuotient );
+
+    loop
+    {
+        if ( deg < newhilb->length() )
+        {
+            if ( deg < source->length() )
+                numelems= (*newhilb)[deg]-(*source)[deg];
+            else
+                numelems= (*newhilb)[deg];
+        }
+        else
+        {
+            if (deg < source->length())
+                numelems= -(*source)[deg];
+            else
+            {
+                deg= 0;
+                return 0;
+            }
+        }
+        if (numelems != 0)
+            return numelems;
+        deg++;
+    }
+    delete newhilb;
+}
+
+void
+generateMonoms( poly m, int var, int deg, homogData * dat )
+{
+    if ( var == pVariables ) {
+        BOOLEAN inSource = FALSE;
+        BOOLEAN inDest = FALSE;
+        poly mon = pCopy( m );
+        pSetExp( mon, var, deg );
+        pSetm( mon );
+        ++dat->overall;
+        int i;
+        for ( i= dat->numSourceHeads - 1; (i >= 0) && (inSource==FALSE); i-- ) {
+            if ( pDivisibleBy( dat->sourceHeads[i].dm, mon ) ) {
+                inSource= TRUE;
+            }
+        }
+        for ( i= dat->numDestPolys - 1; (i >= 0) && (inDest==FALSE); i-- ) {
+            if ( pDivisibleBy( (dat->destIdeal->m)[i], mon ) ) {
+                inDest= TRUE;
+            }
+        }
+        if ( (!inSource) || (!inDest) ) {
+            int basis = 0;
+            if ( !inSource )
+                basis= ++(dat->basisSize);
+            if ( !inDest )
+                ++dat->numberofdestbasismonoms;
+            if ( dat->numMonoms == dat->monlistmax ) {
+                int k;
+#ifdef HAVE_EXPLICIT_CONSTR
+		// Expand array using Singulars ReAlloc function
+                dat->monlist=
+		    (homogElem * )omReallocSize( dat->monlist,
+					   (dat->monlistmax)*sizeof( homogElem ),
+					   (dat->monlistmax+dat->monlistblock) * sizeof( homogElem ) );
+                for ( k= dat->monlistmax; k < (dat->monlistmax+dat->monlistblock); k++ )
+                    dat->monlist[k].homogElem();
+#else
+		// Expand array by generating new one and copying
+		int newsize = dat->monlistmax  + dat->monlistblock;
+		homogElem * tempelem = new homogElem[ newsize ];
+		// Copy old elements
+		for ( k= dat->monlistmax - 1; k >= 0; k-- )
+		    tempelem[k].initialize( dat->monlist[k] );
+		delete [] homogElem;
+		homogElem = tempelem;
+#endif
+                dat->monlistmax+= dat->monlistblock;
+            }
+#ifdef HAVE_EXPLICIT_CONSTR
+            dat->monlist[dat->numMonoms]= homogElem( mon, basis, inDest );
+#else
+	    dat->monlist[dat->numMonoms].initialize( mon, basis, inDest );
+#endif
+            dat->numMonoms++;
+            if ( inSource && ! inDest ) PROT( "\\" );
+            if ( ! inSource && inDest ) PROT( "/" );
+            if ( ! inSource && ! inDest ) PROT( "." );
+        }
+        else {
+            pDelete( & mon );
+        }
+        return;
+    }
+    else {
+        poly newm = pCopy( m );
+        while ( deg >= 0 ) {
+            generateMonoms( newm, var+1, deg, dat );
+            pIncrExp( newm, var );
+            pSetm( newm );
+            deg--;
+        }
+        pDelete( & newm );
+    }
+    return;
+}
+
+void
+mapMonoms( ring oldRing, homogData & dat )
+{
+    int * vperm = (int *)omAlloc( (currRing->N + 1)*sizeof(int) );
+    maFindPerm( oldRing->names, oldRing->N, NULL, 0, currRing->names, currRing->N, NULL, 0, vperm, NULL );
+    //nSetMap( oldRing->ch, oldRing->parameter, oldRing->P, oldRing->minpoly );
+    nSetMap( oldRing );
+    int s;
+    for ( s= dat.numMonoms - 1; s >= 0; s-- ) {
+//        dat.monlist[s].mon.sm= pPermPoly( dat.monlist[s].mon.dm, vperm, currRing->N, NULL, 0 );
+      // obachman: changed the folowing to reflect the new calling interface of
+      // pPermPoly -- Tim please check whether this is correct!
+        dat.monlist[s].mon.sm= pPermPoly( dat.monlist[s].mon.dm, vperm, oldRing, NULL, 0 );
+    }
+}
+
+void
+getVectorRep( homogData & dat )
+{
+    // Calculate the NormalForms
+    int s;
+    for ( s= 0;  s < dat.numMonoms; s++ ) {
+        if ( dat.monlist[s].inDest == FALSE ) {
+            fglmVector v;
+            if ( dat.monlist[s].basis == 0 ) {
+                v= fglmVector( dat.basisSize );
+                // now the monom is in L(source)
+                PROT( "(" );
+                poly nf = kNF( dat.sourceIdeal, NULL, dat.monlist[s].mon.sm );
+                PROT( ")" );
+                poly temp = nf;
+                while (temp != NULL ) {
+                    int t;
+                    for ( t= dat.numMonoms - 1; t >= 0; t-- ) {
+                        if ( dat.monlist[t].basis > 0 ) {
+                            if ( pLmEqual( dat.monlist[t].mon.sm, temp ) ) {
+                                number coeff= nCopy( pGetCoeff( temp ) );
+                                v.setelem( dat.monlist[t].basis, coeff );
+                            }
+                        }
+                    }
+                    pIter(temp);
+                }
+                pDelete( & nf );
+            }
+            else {
+                PROT( "." );
+                v= fglmVector( dat.basisSize, dat.monlist[s].basis );
+            }
+            dat.monlist[s].v= v;
+        }
+    }
+}
+
+void
+remapVectors( ring oldring, homogData & dat )
+{
+    //nSetMap( oldring->ch, oldring->parameter, oldring->P, oldring->minpoly );
+    nSetMap( oldring );
+    int s;
+    for ( s= dat.numMonoms - 1; s >= 0; s-- ) {
+        if ( dat.monlist[s].inDest == FALSE ) {
+            int k;
+            fglmVector newv( dat.basisSize );
+            for ( k= dat.basisSize; k > 0; k-- ){
+                number newnum= nMap( dat.monlist[s].v.getelem( k ) );
+                newv.setelem( k, newnum );
+            }
+            dat.monlist[s].dv= newv;
+        }
+    }
+}
+
+void
+gaussreduce( homogData & dat, int maxnum, int BS )
+{
+    int s;
+    int found= 0;
+
+    int destbasisSize = 0;
+    gaussReducer gauss( dat.basisSize );
+
+    for ( s= 0; (s < dat.numMonoms) && (found < maxnum); s++ ) {
+        if ( dat.monlist[s].inDest == FALSE ) {
+            if ( gauss.reduce( dat.monlist[s].dv ) == FALSE ) {
+                destbasisSize++;
+                dat.monlist[s].destbasis= destbasisSize;
+                gauss.store();
+                PROT( "." );
+            }
+            else {
+                fglmVector p= gauss.getDependence();
+                poly result = pCopy( dat.monlist[s].mon.dm );
+                pSetCoeff( result, nCopy( p.getconstelem( p.size() ) ) );
+                int l = 0;
+                int k;
+                for ( k= 1; k < p.size(); k++ ) {
+                    if ( ! p.elemIsZero( k ) ) {
+                        while ( dat.monlist[l].destbasis != k )
+                            l++;
+                        poly temp = pCopy( dat.monlist[l].mon.dm );
+                        pSetCoeff( temp, nCopy( p.getconstelem( k ) ) );
+                        result= pAdd( result, temp );
+                    }
+                }
+                if ( ! nGreaterZero( pGetCoeff( result ) ) ) result= pNeg( result );
+//                PROT2( "(%s)", pString( result ) );
+                PROT( "+" );
+                found++;
+                (dat.destIdeal->m)[dat.numDestPolys]= result;
+                dat.numDestPolys++;
+                if ( IDELEMS(dat.destIdeal) == dat.numDestPolys ) {
+                    pEnlargeSet( & dat.destIdeal->m, IDELEMS( dat.destIdeal ), BS );
+                    IDELEMS( dat.destIdeal )+= BS;
+                }
+
+            }
+
+        }
+    }
+    PROT2( "(%i", s );
+    PROT2( "/%i)", dat.numberofdestbasismonoms );
+}
+
+
+BOOLEAN
+fglmhomog( idhdl sourceRingHdl, ideal sourceIdeal, idhdl destRingHdl, ideal & destIdeal )
+{
+#define groebnerBS 16
+    int numGBelems;
+    int deg = 0;
+
+    homogData dat;
+
+    // get the hilbert series and the leading monomials of the sourceIdeal:
+    rSetHdl( sourceRingHdl, TRUE );
+    ring sourceRing = currRing;
+
+    intvec * hilb = hHstdSeries( sourceIdeal, NULL, currQuotient );
+    int s;
+    dat.sourceIdeal= sourceIdeal;
+    dat.sourceHeads= (doublepoly *)omAlloc( IDELEMS( sourceIdeal ) * sizeof( doublepoly ) );
+    for ( s= IDELEMS( sourceIdeal ) - 1; s >= 0; s-- ) {
+        dat.sourceHeads[s].sm= pHead( (sourceIdeal->m)[s] );
+    }
+    dat.numSourceHeads= IDELEMS( sourceIdeal );
+    rSetHdl( destRingHdl, TRUE );
+    ring destRing = currRing;
+
+    // Map the sourceHeads to the destRing
+    int * vperm = (int *)omAlloc( (sourceRing->N + 1)*sizeof(int) );
+    maFindPerm( sourceRing->names, sourceRing->N, NULL, 0, currRing->names,
+                currRing->N, NULL, 0, vperm, NULL, currRing->ch);
+    //nSetMap( sourceRing->ch, sourceRing->parameter, sourceRing->P, sourceRing->minpoly );
+    nSetMap( sourceRing );
+    for ( s= IDELEMS( sourceIdeal ) - 1; s >= 0; s-- ) {
+        dat.sourceHeads[s].dm= pPermPoly( dat.sourceHeads[s].sm, vperm, sourceRing, NULL, 0 );
+    }
+
+    dat.destIdeal= idInit( groebnerBS, 1 );
+    dat.numDestPolys= 0;
+
+    while ( (numGBelems= hfglmNextdegree( hilb, dat.destIdeal, deg )) != 0 ) {
+        int num = 0;  // the number of monoms of degree deg
+        PROT2( "deg= %i ", deg );
+        PROT2( "num= %i\ngen>", numGBelems );
+        dat.monlistblock= 512;
+        dat.monlistmax= dat.monlistblock;
+#ifdef HAVE_EXPLICIT_CONSTR
+        dat.monlist= (homogElem *)omAlloc( dat.monlistmax*sizeof( homogElem ) );
+        int j;
+        for ( j= dat.monlistmax - 1; j >= 0; j-- ) dat.monlist[j].homogElem();
+#else
+	dat.monlist = new homogElem[ dat.monlistmax ];
+#endif
+        dat.numMonoms= 0;
+        dat.basisSize= 0;
+        dat.overall= 0;
+        dat.numberofdestbasismonoms= 0;
+
+        poly start= pOne();
+        generateMonoms( start, 1, deg, &dat );
+        pDelete( & start );
+
+        PROT2( "(%i/", dat.basisSize );
+        PROT2( "%i)\nvec>", dat.overall );
+        // switch to sourceRing and map monoms
+        rSetHdl( sourceRingHdl, TRUE );
+        mapMonoms( destRing, dat );
+        getVectorRep( dat );
+
+        // switch to destination Ring and remap the vectors
+        rSetHdl( destRingHdl, TRUE );
+        remapVectors( sourceRing, dat );
+
+        PROT( "<\nred>" );
+        // now do gaussian reduction
+        gaussreduce( dat, numGBelems, groebnerBS );
+
+#ifdef HAVE_EXPLICIT_CONSTR
+        omFreeSize( (ADDRESS)dat.monlist, dat.monlistmax*sizeof( homogElem ) );
+#else
+	delete [] dat.monlist;
+#endif
+        PROT( "<\n" );
+    }
+    PROT( "\n" );
+    destIdeal= dat.destIdeal;
+    idSkipZeroes( destIdeal );
+    return TRUE;
+}
+
+ideal
+fglmhomProc(leftv first, leftv second)
+{
+    idhdl dest= currRingHdl;
+    ideal result;
+    // in den durch das erste Argument angegeben Ring schalten:
+    rSetHdl( (idhdl)first->data, TRUE );
+    idhdl ih= currRing->idroot->get( second->name, myynest );
+    ASSERT( ih!=NULL, "Error: Can't find ideal in ring");
+    rSetHdl( dest, TRUE );
+
+    ideal i= IDIDEAL(ih);
+    fglmhomog( (idhdl)first->data, i, dest, result );
+
+    return( result );
+}
+
+#endif
+
+// Questions:
+// Muss ich einen intvec freigeben?
+// ----------------------------------------------------------------------------
+// Local Variables: ***
+// compile-command: "make Singular" ***
+// page-delimiter: "^\\(
+\\|//!\\)" ***
+// fold-internal-margins: nil ***
+// End: ***
Index: kernel/fglmvec.cc
===================================================================
--- kernel/fglmvec.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/fglmvec.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,502 @@
+// emacs edit mode for this file is -*- C++ -*-
+// $Id: fglmvec.cc,v 1.1.1.1 2003-10-06 12:15:53 Singular Exp $
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - The FGLM-Algorithm
+*   Implementation of number-vectors for the fglm algorithm.
+*   (See fglm.cc). Based on a letter-envelope implementation, mainly
+*   written to be used by the fglm algorithm. Hence they are
+*   specialized for this purpose.
+*/
+
+#include "mod2.h"
+
+#ifdef HAVE_FGLM
+#include "omalloc.h"
+#include "structs.h"
+#include "numbers.h"
+#include "fglm.h"
+#include "fglmvec.h"
+
+#define PROT(msg)
+#define STICKYPROT(msg) if (BTEST1(OPT_PROT)) Print(msg)
+#define PROT2(msg,arg)
+#define STICKYPROT2(msg,arg) if (BTEST1(OPT_PROT)) Print(msg,arg)
+#define fglmASSERT(ignore1,ignore2)
+
+class fglmVectorRep
+{
+private:
+    int ref_count;
+    int N;
+    number * elems;
+public:
+    fglmVectorRep() : ref_count(1), N(0), elems(0) {}
+    fglmVectorRep( int n, number * e ) : ref_count(1), N(n), elems(e) {}
+    fglmVectorRep( int n ) : ref_count(1), N(n)
+    {
+        fglmASSERT( N >= 0, "illegal Vector representation" );
+        if ( N == 0 )
+            elems= 0;
+        else {
+            elems= (number *)omAlloc( N*sizeof( number ) );
+            for ( int i= N-1; i >= 0; i-- )
+                elems[i]= nInit( 0 );
+        }
+    }
+    ~fglmVectorRep()
+    {
+        if ( N > 0 ) {
+            for ( int i= N-1; i >= 0; i-- )
+                nDelete( elems + i );
+            omFreeSize( (ADDRESS)elems, N*sizeof( number ) );
+        }
+    }
+
+    fglmVectorRep* clone() const
+    {
+        if ( N > 0 ) {
+            number * elems_clone;
+            elems_clone= (number *)omAlloc( N*sizeof( number ) );
+            for ( int i= N-1; i >= 0; i-- )
+                elems_clone[i] = nCopy( elems[i] );
+            return new fglmVectorRep( N, elems_clone );
+        } else
+            return new fglmVectorRep( N, 0 );
+    }
+    BOOLEAN deleteObject() { return --ref_count == 0; }
+    fglmVectorRep * copyObject() { ref_count++; return this; }
+    int refcount() const { return ref_count; }
+    BOOLEAN isUnique() const { return ref_count == 1; }
+
+    int size() const { return N; }
+    int isZero() const
+    {
+        int k;
+        for ( k= N; k > 0; k-- )
+            if ( ! nIsZero( getconstelem( k ) ) )
+                return 0;
+        return 1;
+    }
+    int numNonZeroElems() const
+    {
+        int num = 0;
+        int k;
+        for ( k= N; k > 0; k-- )
+            if ( ! nIsZero( getconstelem( k ) ) ) num++;
+        return num;
+    }
+    void setelem( int i, number n )
+    {
+        fglmASSERT( 0 < i && i <= N, "setelem: wrong index" );
+        nDelete( elems + i-1 );
+        elems[i-1]= n;
+    }
+    number ejectelem( int i, number n )
+    {
+        fglmASSERT( isUnique(), "should only be called if unique!" );
+        number temp= elems[i-1];
+        elems[i-1]= n;
+        return temp;
+    }
+    number & getelem( int i )
+    {
+        fglmASSERT( 0 < i && i <= N, "getelem: wrong index" );
+        return elems[i-1];
+    }
+    const number getconstelem( int i) const
+    {
+        fglmASSERT( 0 < i && i <= N, "getconstelem: wrong index" );
+        return elems[i-1];
+    }
+    friend class fglmVector;
+};
+
+
+///--------------------------------------------------------------------------------
+/// Implementation of class fglmVector
+///--------------------------------------------------------------------------------
+
+fglmVector::fglmVector( fglmVectorRep * r ) : rep(r) {}
+
+fglmVector::fglmVector() : rep( new fglmVectorRep() ) {}
+
+fglmVector::fglmVector( int size ) : rep( new fglmVectorRep( size ) ) {}
+
+fglmVector::fglmVector( int size, int basis ) : rep( new fglmVectorRep( size ) )
+{
+    rep->setelem( basis, nInit( 1 ) );
+}
+
+fglmVector::fglmVector( const fglmVector & v )
+{
+    rep= v.rep->copyObject();
+}
+
+fglmVector::~fglmVector()
+{
+    if ( rep->deleteObject() )
+        delete rep;
+}
+
+#ifndef HAVE_EXPLICIT_CONSTR
+void
+fglmVector::mac_constr( const fglmVector & v)
+{
+    rep= v.rep->copyObject();
+}
+
+void
+fglmVector::mac_constr_i( int size )
+{
+    rep= new fglmVectorRep( size );
+}
+
+void
+fglmVector::clearelems()
+{
+    if ( rep->deleteObject() )
+      delete rep;
+}
+#endif
+
+void
+fglmVector::makeUnique()
+{
+    if ( rep->refcount() != 1 ) {
+        rep->deleteObject();
+        rep= rep->clone();
+    }
+}
+
+int
+fglmVector::size() const
+{
+    return rep->size();
+}
+
+int
+fglmVector::numNonZeroElems() const
+{
+    return rep->numNonZeroElems();
+}
+
+void
+fglmVector::nihilate( const number fac1, const number fac2, const fglmVector v )
+{
+    int i;
+    int vsize= v.size();
+    number term1, term2;
+    fglmASSERT( vsize <= rep->size(), "v has to be smaller oder equal" );
+    if ( rep->isUnique() ) {
+        for ( i= vsize; i > 0; i-- ) {
+            term1= nMult( fac1, rep->getconstelem( i ) );
+            term2= nMult( fac2, v.rep->getconstelem( i ) );
+            rep->setelem( i, nSub( term1, term2 ) );
+            nDelete( &term1 );
+            nDelete( &term2 );
+        }
+        for ( i= rep->size(); i > vsize; i-- ) {
+            rep->setelem( i, nMult( fac1, rep->getconstelem( i ) ) );
+        }
+    }
+    else
+    {
+        number* newelems;
+        newelems= (number *)omAlloc( rep->size()*sizeof( number ) );
+        for ( i= vsize; i > 0; i-- ) {
+            term1= nMult( fac1, rep->getconstelem( i ) );
+            term2= nMult( fac2, v.rep->getconstelem( i ) );
+            newelems[i-1]= nSub( term1, term2 );
+            nDelete( &term1 );
+            nDelete( &term2 );
+        }
+        for ( i= rep->size(); i > vsize; i-- ) {
+            newelems[i-1]= nMult( fac1, rep->getconstelem( i ) );
+        }
+        rep->deleteObject();
+        rep= new fglmVectorRep( rep->size(), newelems );
+    }
+}
+
+fglmVector &
+fglmVector::operator = ( const fglmVector & v )
+{
+    if ( this != &v ) {
+        if ( rep->deleteObject() )
+            delete rep;
+        rep = v.rep->copyObject();
+    }
+    return *this;
+}
+
+int
+fglmVector::operator == ( const fglmVector & v )
+{
+    if ( rep->size() == v.rep->size() ) {
+        if ( rep == v.rep ) return 1;
+        else {
+            int i;
+            for ( i= rep->size(); i > 0; i-- )
+                if ( ! nEqual( rep->getconstelem( i ), v.rep->getconstelem( i ) ) )
+                    return 0;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+int
+fglmVector::operator != ( const fglmVector & v )
+{
+    return !( *this == v );
+}
+
+int
+fglmVector::isZero()
+{
+    return rep->isZero();
+}
+
+int
+fglmVector::elemIsZero( int i )
+{
+    return nIsZero( rep->getconstelem( i ) );
+}
+
+fglmVector &
+fglmVector::operator += ( const fglmVector & v )
+{
+    fglmASSERT( size() == v.size(), "incompatible vectors" );
+    // ACHTUNG : Das Verhalten hier mit gcd genau ueberpruefen!
+    int i;
+    if ( rep->isUnique() ) {
+        for ( i= rep->size(); i > 0; i-- )
+            rep->setelem( i, nAdd( rep->getconstelem( i ), v.rep->getconstelem( i ) ) );
+    }
+    else
+    {
+        int n = rep->size();
+        number* newelems;
+        newelems= (number *)omAlloc( n*sizeof( number ) );
+        for ( i= n; i > 0; i-- )
+            newelems[i-1]= nAdd( rep->getconstelem( i ), v.rep->getconstelem( i ) );
+        rep->deleteObject();
+        rep= new fglmVectorRep( n, newelems );
+    }
+    return *this;
+}
+
+fglmVector &
+fglmVector::operator -= ( const fglmVector & v )
+{
+    fglmASSERT( size() == v.size(), "incompatible vectors" );
+    int i;
+    if ( rep->isUnique() ) {
+        for ( i= rep->size(); i > 0; i-- )
+            rep->setelem( i, nSub( rep->getconstelem( i ), v.rep->getconstelem( i ) ) );
+    }
+    else
+    {
+        int n = rep->size();
+        number* newelems;
+        newelems= (number *)omAlloc( n*sizeof( number ) );
+        for ( i= n; i > 0; i-- )
+            newelems[i-1]= nSub( rep->getconstelem( i ), v.rep->getconstelem( i ) );
+        rep->deleteObject();
+        rep= new fglmVectorRep( n, newelems );
+    }
+    return *this;
+}
+
+fglmVector &
+fglmVector::operator *= ( const number & n )
+{
+    int s= rep->size();
+    int i;
+    if ( ! rep->isUnique() ) {
+        number * temp;
+        temp= (number *)omAlloc( s*sizeof( number ) );
+        for ( i= s; i > 0; i-- )
+            temp[i-1]= nMult( rep->getconstelem( i ), n );
+        rep->deleteObject();
+        rep= new fglmVectorRep( s, temp );
+    }
+    else
+    {
+        for (i= s; i > 0; i-- )
+            rep->setelem( i, nMult( rep->getconstelem( i ), n ) );
+    }
+    return *this;
+}
+
+fglmVector &
+fglmVector::operator /= ( const number & n )
+{
+    int s= rep->size();
+    int i;
+    if ( ! rep->isUnique() ) {
+        number * temp;
+        temp= (number *)omAlloc( s*sizeof( number ) );
+        for ( i= s; i > 0; i-- ) {
+            temp[i-1]= nDiv( rep->getconstelem( i ), n );
+            nNormalize( temp[i-1] );
+        }
+        rep->deleteObject();
+        rep= new fglmVectorRep( s, temp );
+    }
+    else
+    {
+        for (i= s; i > 0; i-- ) {
+            rep->setelem( i, nDiv( rep->getconstelem( i ), n ) );
+            nNormalize( rep->getelem( i ) );
+        }
+    }
+    return *this;
+}
+
+fglmVector
+operator - ( const fglmVector & v )
+{
+    fglmVector temp( v.size() );
+    int i;
+    number n ;
+    for ( i= v.size(); i > 0; i-- ) {
+        n= nCopy( v.getconstelem( i ) );
+        n= nNeg( n );
+        temp.setelem( i, n );
+    }
+    return temp;
+}
+
+fglmVector
+operator + ( const fglmVector & lhs, const fglmVector & rhs )
+{
+    fglmVector temp= lhs;
+    temp+= rhs;
+    return temp;
+}
+
+fglmVector
+operator - ( const fglmVector & lhs, const fglmVector & rhs )
+{
+    fglmVector temp= lhs;
+    temp-= rhs;
+    return temp;
+}
+
+fglmVector
+operator * ( const fglmVector & v, const number n )
+{
+    fglmVector temp= v;
+    temp*= n;
+    return temp;
+}
+
+fglmVector
+operator * ( const number n, const fglmVector & v )
+{
+    fglmVector temp= v;
+    temp*= n;
+    return temp;
+}
+
+number &
+fglmVector::getelem( int i )
+{
+    makeUnique();
+    return rep->getelem( i );
+}
+
+number
+fglmVector::getconstelem( int i ) const
+{
+    return rep->getconstelem( i );
+}
+
+void
+fglmVector::setelem( int i, number & n )
+{
+    makeUnique();
+    rep->setelem( i, n );
+    n= nNULL;
+}
+
+number
+fglmVector::gcd() const
+{
+    int i= rep->size();
+    BOOLEAN found = FALSE;
+    BOOLEAN gcdIsOne = FALSE;
+    number theGcd;
+    number current;
+    while( i > 0 && ! found ) {
+        current= rep->getconstelem( i );
+        if ( ! nIsZero( current ) ) {
+            theGcd= nCopy( current );
+            found= TRUE;
+            if ( ! nGreaterZero( theGcd ) ) {
+                theGcd= nNeg( theGcd );
+            }
+            if ( nIsOne( theGcd ) ) gcdIsOne= TRUE;
+        }
+        i--;
+    }
+    if ( found ) {
+        while ( i > 0 && ! gcdIsOne ) {
+            current= rep->getconstelem( i );
+            if ( ! nIsZero( current ) ) {
+                number temp= nGcd( theGcd, current, currRing );
+                nDelete( &theGcd );
+                theGcd= temp;
+                if ( nIsOne( theGcd ) ) gcdIsOne= TRUE;
+            }
+            i--;
+        }
+    }
+    else
+        theGcd= nInit( 0 );
+    return theGcd;
+}
+
+number
+fglmVector::clearDenom()
+{
+    number theLcm = nInit( 1 );
+    number current;
+    BOOLEAN isZero = TRUE;
+    int i;
+    for ( i= size(); i > 0; i-- ) {
+        if ( ! nIsZero( rep->getconstelem(i) ) ) {
+            isZero= FALSE;
+            number temp= nLcm( theLcm, rep->getconstelem( i ), currRing );
+            nDelete( &theLcm );
+            theLcm= temp;
+        }
+    }
+    if ( isZero ) {
+        nDelete( &theLcm );
+        theLcm= nInit( 0 );
+    }
+    else {
+        if ( ! nIsOne( theLcm ) ) {
+            *this *= theLcm;
+            for ( i= size(); i > 0; i-- ) {
+                nNormalize( rep->getelem( i ) );
+            }
+        }
+    }
+    return theLcm;
+}
+
+#endif
+// ----------------------------------------------------------------------------
+// Local Variables: ***
+// compile-command: "make Singular" ***
+// page-delimiter: "^\\(
+\\|//!\\)" ***
+// fold-internal-margins: nil ***
+// End: ***
Index: kernel/fglmvec.h
===================================================================
--- kernel/fglmvec.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/fglmvec.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,65 @@
+// emacs edit mode for this file is -*- C++ -*-
+// $Id: fglmvec.h,v 1.1.1.1 2003-10-06 12:15:53 Singular Exp $
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - The FGLM-Algorithm
+*   header file for fglmvec.cc. See fglmvec.cc for details.
+*/
+
+#ifndef FGLMVEC_H
+#define FGLMVEC_H
+
+#include "numbers.h"
+
+class fglmVectorRep;
+
+class fglmVector
+{
+protected:
+    fglmVectorRep * rep;
+    void makeUnique();
+    fglmVector( fglmVectorRep * rep );
+public:
+    fglmVector();
+    fglmVector( int size );
+    fglmVector( int size, int basis );
+    fglmVector( const fglmVector & v );
+    ~fglmVector();
+#ifndef HAVE_EXPLICIT_CONSTR
+    void mac_constr( const fglmVector & v);
+    void mac_constr_i( int size);
+    void clearelems();
+#endif
+    int size() const;
+    int numNonZeroElems() const;
+
+    void nihilate( const number fac1, const number fac2, const fglmVector v );
+    fglmVector & operator = ( const fglmVector & v );
+
+    int operator == ( const fglmVector & );
+    int operator != ( const fglmVector & );
+    int isZero();
+    int elemIsZero( int i );
+
+    fglmVector & operator += ( const fglmVector & );
+    fglmVector & operator -= ( const fglmVector & );
+    fglmVector & operator *= ( const number & );
+    fglmVector & operator /= ( const number & );
+    friend fglmVector operator - ( const fglmVector & v );
+    friend fglmVector operator + ( const fglmVector & lhs, const fglmVector & rhs );
+    friend fglmVector operator - ( const fglmVector & lhs, const fglmVector & rhs );
+    friend fglmVector operator * ( const fglmVector & v, const number n );
+    friend fglmVector operator * ( const number n, const fglmVector & v );
+
+    number getconstelem( int i ) const;
+    number & getelem( int i );
+    void setelem( int i, number & n );
+
+    number gcd() const;
+    number clearDenom();
+};
+
+#endif
Index: kernel/fglmzero.cc
===================================================================
--- kernel/fglmzero.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/fglmzero.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1213 @@
+// emacs edit mode for this file is -*- C++ -*-
+// $Id: fglmzero.cc,v 1.1.1.1 2003-10-06 12:15:53 Singular Exp $
+
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - The FGLM-Algorithm
+*   Implementation of the fglm algorithm for 0-dimensional ideals,
+*   based on an idea by Faugere/Gianni/Lazard and Mora.
+*   The procedure CalculateFunctionals calculates the functionals
+*   which define the given ideal in the source ring. They build the
+*   input for GroebnerViaFunctionals, which defines the reduced
+*   groebner basis for the ideal in the destination ring.
+*/
+
+/* Changes:
+ * o FindUnivariatePolys added
+ */
+
+#include "mod2.h"
+
+#ifdef HAVE_FGLM
+#include "structs.h"
+#include "polys.h"
+#include "ideals.h"
+#include "ring.h"
+#include "febase.h"
+#include "maps.h"
+#include "omalloc.h"
+#include "kstd1.h" // for kNF (see fglmquot)
+#include "intvec.h" 
+#include "fglm.h"
+#include "fglmvec.h"
+#include "fglmgauss.h"
+// assumes, that NOSTREAMIO is set in factoryconf.h, which is included
+// by templates/list.h.
+#include <templates/ftmpl_list.h>
+#define PROT(msg)
+#define STICKYPROT(msg) if (BTEST1(OPT_PROT)) Print(msg)
+#define PROT2(msg,arg)
+#define STICKYPROT2(msg,arg) if (BTEST1(OPT_PROT)) Print(msg,arg)
+#define fglmASSERT(ignore1,ignore2)
+
+
+
+// internal Version: 1.3.1.12
+// ============================================================
+//!      The idealFunctionals
+// ============================================================
+
+struct matElem
+{
+    int row;
+    number elem;
+};
+
+struct matHeader
+{
+    int size;
+    BOOLEAN owner;
+    matElem * elems;
+};
+
+class idealFunctionals
+{
+private:
+    int _block;
+    int _max;
+    int _size;
+    int _nfunc;
+    int * currentSize;
+    matHeader ** func;
+    matHeader * grow( int var );
+public:
+    idealFunctionals( int blockSize, int numFuncs );
+    ~idealFunctionals();
+
+    int dimen() const { fglmASSERT( _size>0, "called to early"); return _size; }
+    void endofConstruction();
+    void map( ring source );
+    void insertCols( int * divisors, int to );
+    void insertCols( int * divisors, const fglmVector to );
+    fglmVector addCols( const int var, int basisSize, const fglmVector v ) const;
+    fglmVector multiply( const fglmVector v, int var ) const;
+};
+
+
+idealFunctionals::idealFunctionals( int blockSize, int numFuncs )
+{
+    int k;
+    _block= blockSize;
+    _max= _block;
+    _size= 0;
+    _nfunc= numFuncs;
+
+    currentSize= (int *)omAlloc( _nfunc*sizeof( int ) );
+    for ( k= _nfunc-1; k >= 0; k-- )
+        currentSize[k]= 0;
+
+    func= (matHeader **)omAlloc( _nfunc*sizeof( matHeader * ) );
+    for ( k= _nfunc-1; k >= 0; k-- )
+        func[k]= (matHeader *)omAlloc( _max*sizeof( matHeader ) );
+}
+
+idealFunctionals::~idealFunctionals()
+{
+    int k;
+    int l;
+    int row;
+    matHeader * colp;
+    matElem * elemp;
+    for ( k= _nfunc-1; k >= 0; k-- ) {
+        for ( l= _size-1, colp= func[k]; l >= 0; l--, colp++ ) {
+            if ( ( colp->owner == TRUE ) && ( colp->size > 0 ) ) {
+                for ( row= colp->size-1, elemp= colp->elems; row >= 0; row--, elemp++ )
+                    nDelete( & elemp->elem );
+                omFreeSize( (ADDRESS)colp->elems, colp->size*sizeof( matElem ) );
+            }
+        }
+        omFreeSize( (ADDRESS)func[k], _max*sizeof( matHeader ) );
+    }
+    omFreeSize( (ADDRESS)func, _nfunc*sizeof( matHeader * ) );
+    omFreeSize( (ADDRESS)currentSize, _nfunc*sizeof( int ) );
+}
+
+void
+idealFunctionals::endofConstruction()
+{
+    _size= currentSize[0];
+}
+
+void
+idealFunctionals::map( ring source )
+{
+    // maps from ring source to currentRing.
+    int var, col, row;
+    matHeader * colp;
+    matElem * elemp;
+    number newelem;
+
+    int * perm = (int *)omAlloc0( (_nfunc+1)*sizeof( int ) );
+    maFindPerm( source->names, source->N, NULL, 0, currRing->names,
+                currRing->N, NULL, 0, perm, NULL , currRing->ch);
+    nMapFunc nMap=nSetMap( source);
+
+    matHeader ** temp = (matHeader **)omAlloc( _nfunc*sizeof( matHeader * ));
+    for ( var= 0; var < _nfunc; var ++ ) {
+        for ( col= 0, colp= func[var]; col < _size; col++, colp++ ) {
+            if ( colp->owner == TRUE ) {
+                for ( row= colp->size-1, elemp= colp->elems; row >= 0;
+                  row--, elemp++ )
+                {
+                    newelem= nMap( elemp->elem );
+                    nDelete( & elemp->elem );
+                    elemp->elem= newelem;
+                }
+            }
+        }
+        temp[ perm[var+1]-1 ]= func[var];
+    }
+    omFreeSize( (ADDRESS)func, _nfunc*sizeof( matHeader * ) );
+    omFreeSize( (ADDRESS)perm, (_nfunc+1)*sizeof( int ) );
+    func= temp;
+}
+
+matHeader *
+idealFunctionals::grow( int var )
+{
+    if ( currentSize[var-1] == _max ) {
+        int k;
+        for ( k= _nfunc; k > 0; k-- )
+            func[k-1]= (matHeader *)omReallocSize( func[k-1], _max*sizeof( matHeader ), (_max + _block)*sizeof( matHeader ) );
+        _max+= _block;
+    }
+    currentSize[var-1]++;
+    return func[var-1] + currentSize[var-1] - 1;
+}
+
+void
+idealFunctionals::insertCols( int * divisors, int to )
+{
+    fglmASSERT( 0 < divisors[0] && divisors[0] <= _nfunc, "wrong number of divisors" );
+    int k;
+    BOOLEAN owner = TRUE;
+    matElem * elems = (matElem *)omAlloc( sizeof( matElem ) );
+    elems->row= to;
+    elems->elem= nInit( 1 );
+    for ( k= divisors[0]; k > 0; k-- ) {
+        fglmASSERT( 0 < divisors[k] && divisors[k] <= _nfunc, "wrong divisor" );
+        matHeader * colp = grow( divisors[k] );
+        colp->size= 1;
+        colp->elems= elems;
+        colp->owner= owner;
+        owner= FALSE;
+    }
+}
+
+
+void
+idealFunctionals::insertCols( int * divisors, const fglmVector to )
+{
+    // divisors runs from divisors[0]..divisors[size-1]
+    fglmASSERT( 0 < divisors[0] && divisors[0] <= _nfunc, "wrong number of divisors" );
+    int k, l;
+    int numElems= to.numNonZeroElems();
+    matElem * elems;
+    matElem * elemp;
+    BOOLEAN owner = TRUE;
+    if ( numElems > 0 ) {
+        elems= (matElem *)omAlloc( numElems * sizeof( matElem ) );
+        for ( k= 1, l= 1, elemp= elems; k <= numElems; k++, elemp++ ) {
+            while ( nIsZero( to.getconstelem(l) ) ) l++;
+            elemp->row= l;
+            elemp->elem= nCopy( to.getconstelem( l ) );
+            l++; // hochzaehlen, damit wir nicht noch einmal die gleiche Stelle testen
+        }
+    }
+    else
+        elems= NULL;
+    for ( k= divisors[0]; k > 0; k-- ) {
+        fglmASSERT( 0 < divisors[k] && divisors[k] <= _nfunc, "wrong divisor" );
+        matHeader * colp = grow( divisors[k] );
+        colp->size= numElems;
+        colp->elems= elems;
+        colp->owner= owner;
+        owner= FALSE;
+    }
+}
+
+fglmVector
+idealFunctionals::addCols( const int var, int basisSize, const fglmVector v ) const
+{
+    fglmVector result( basisSize );
+    matHeader * colp;
+    matElem * elemp;
+    number factor, temp;
+    int k, l;
+    int vsize = v.size();
+
+    fglmASSERT( currentSize[var-1]+1 >= vsize, "wrong v.size()" );
+    for ( k= 1, colp= func[var-1]; k <= vsize; k++, colp++ ) {
+        factor= v.getconstelem( k );
+        if ( ! nIsZero( factor ) ) {
+            for ( l= colp->size-1, elemp= colp->elems; l >= 0; l--, elemp++ ) {
+                temp= nMult( factor, elemp->elem );
+                number newelem= nAdd( result.getconstelem( elemp->row ), temp );
+                nDelete( & temp );
+                nNormalize( newelem );
+                result.setelem( elemp->row, newelem );
+            }
+        }
+    }
+    return result;
+}
+
+fglmVector
+idealFunctionals::multiply( const fglmVector v, int var ) const
+{
+    fglmASSERT( v.size() == _size, "multiply: v has wrong size");
+    fglmVector result( _size );
+    matHeader * colp;
+    matElem * elemp;
+    number factor, temp;
+    int k, l;
+    for ( k= 1, colp= func[var-1]; k <= _size; k++, colp++ ) {
+        factor= v.getconstelem( k );
+        if ( ! nIsZero( factor ) ) {
+            for ( l= colp->size-1, elemp= colp->elems; l >= 0; l--, elemp++ ) {
+                temp= nMult( factor, elemp->elem );
+                number newelem= nAdd( result.getconstelem( elemp->row ), temp );
+                nDelete( & temp );
+                nNormalize( newelem );
+                result.setelem( elemp->row, newelem );
+            }
+        }
+    }
+    return result;
+}
+
+// ============================================================
+//!      The old basis
+// ============================================================
+
+//     Contains the data for a border-monomial, i.e. the monom itself
+//      ( as a Singular-poly ) and its normal-form, described by an
+//      fglmVector. The size of the Vector depends on the current size of
+//      the basis when the normalForm was computed.
+//     monom gets deleted when borderElem comes out of scope.
+class borderElem
+{
+public:
+    poly monom;
+    fglmVector nf;
+    borderElem() : monom(NULL), nf() {}
+    borderElem( poly p, fglmVector n ) : monom( p ), nf( n ) {}
+    ~borderElem() { pDeleteLm(&monom); }
+#ifndef HAVE_EXPLICIT_CONSTR
+    void insertElem( poly p, fglmVector n )
+    {
+        monom= p;
+        nf= n;
+    }
+#endif
+};
+
+//     This class contains the relevant data for the 'candidates'
+//     The declaration of class fglmSelem is found in fglm.h
+
+fglmSelem::fglmSelem( poly p, int var ) : monom( p ), numVars( 0 )
+{
+    for ( int k = pVariables; k > 0; k-- )
+        if ( pGetExp( monom, k ) > 0 )
+            numVars++;
+    divisors= (int *)omAlloc( (numVars+1)*sizeof( int ) );
+    divisors[0]= 0;
+    newDivisor( var );
+}
+
+void
+fglmSelem::cleanup()
+{
+    omFreeSize( (ADDRESS)divisors, (numVars+1)*sizeof( int ) );
+}
+
+//     The data-structure for the Functional-Finding-Algorithm.
+class fglmSdata
+{
+private:
+    ideal theIdeal;
+    int idelems;
+    int* varpermutation;
+
+    int basisBS;
+    int basisMax;
+    int basisSize;
+    polyset basis;  //. rem: runs from basis[1]..basis[dimen]
+
+    int borderBS;
+    int borderMax;
+    int borderSize;
+    borderElem * border;  //. rem: runs from border[1]..border[dimen]
+
+    List<fglmSelem> nlist;
+    BOOLEAN _state;
+public:
+    fglmSdata( const ideal thisIdeal );
+    ~fglmSdata();
+
+    BOOLEAN state() const { return _state; };
+    int getBasisSize() const { return basisSize; };
+    int newBasisElem( poly & p );
+    void newBorderElem( poly & m, fglmVector v );
+    BOOLEAN candidatesLeft() const { return ( nlist.isEmpty() ? FALSE : TRUE ); }
+    fglmSelem nextCandidate();
+    void updateCandidates();
+    int getEdgeNumber( const poly m ) const;
+    poly getSpanPoly( int number ) const { return pCopy( (theIdeal->m)[number-1] ); }
+    fglmVector getVectorRep( const poly m );
+    fglmVector getBorderDiv( const poly m, int & var ) const;
+};
+
+fglmSdata::fglmSdata( const ideal thisIdeal )
+{
+    // An dieser Stelle kann die BlockSize ( =BS ) noch sinnvoller berechnet
+    // werden, jenachdem wie das Ideal aussieht.
+    theIdeal= thisIdeal;
+    idelems= IDELEMS( theIdeal );
+    varpermutation = (int*)omAlloc( (pVariables+1)*sizeof(int) );
+    // Sort ring variables by increasing values (because of weighted orderings)
+    ideal perm = idMaxIdeal(1);
+    intvec *iv = idSort(perm,TRUE);
+    idDelete(&perm);
+    for(int i = pVariables; i > 0; i--) varpermutation[pVariables+1-i] = (*iv)[i-1];
+    delete iv;
+
+    basisBS= 100;
+    basisMax= basisBS;
+    basisSize= 0;
+    basis= (polyset)omAlloc( basisMax*sizeof( poly ) );
+
+    borderBS= 100;
+    borderMax= borderBS;
+    borderSize= 0;
+#ifndef HAVE_EXPLICIT_CONSTR
+    border= new borderElem[ borderMax ];
+#else
+    border= (borderElem *)omAlloc( borderMax*sizeof( borderElem ) );
+#endif
+    // rem: the constructors are called in newBorderElem().
+    _state= TRUE;
+}
+
+fglmSdata::~fglmSdata()
+{
+    omFreeSize( (ADDRESS)varpermutation, (pVariables+1)*sizeof(int) );
+    for ( int k = basisSize; k > 0; k-- )
+        pDeleteLm( basis + k );  //. rem: basis runs from basis[1]..basis[basisSize]
+    omFreeSize( (ADDRESS)basis, basisMax*sizeof( poly ) );
+#ifndef HAVE_EXPLICIT_CONSTR
+    delete [] border;
+#else
+    for ( int l = borderSize; l > 0; l-- )
+        // rem: the polys of borderElem are deleted via ~borderElem()
+        border[l].~borderElem();
+    omFreeSize( (ADDRESS)border, borderMax*sizeof( borderElem ) );
+#endif
+}
+
+//     Inserts poly p without copying into basis, reAllocs Memory if necessary,
+//      increases basisSize and returns the new basisSize.
+//     Remember: The elements of basis are deleted via pDelete in ~fglmSdata!
+//     Sets m= NULL to indicate that now basis is ow(e?)ing the poly.
+int
+fglmSdata::newBasisElem( poly & m )
+{
+    basisSize++;
+    if ( basisSize == basisMax ) {
+        basis= (polyset)omReallocSize( basis, basisMax*sizeof( poly ), (basisMax + basisBS)*sizeof( poly ) );
+        basisMax+= basisBS;
+    }
+    basis[basisSize]= m;
+    m= NULL;
+    return basisSize;
+}
+
+//     Inserts poly p and fglmvector v without copying into border, reAllocs Memory
+//      if necessary, and increases borderSize.
+//     Remember: The poly of border is deleted via ~borderElem in ~fglmSdata!
+//     Sets m= NULL to indicate that now border is ow(e?)ing the poly.
+void
+fglmSdata::newBorderElem( poly & m, fglmVector v )
+{
+    borderSize++;
+    if ( borderSize == borderMax ) {
+#ifndef HAVE_EXPLICIT_CONSTR
+        borderElem * tempborder = new borderElem[ borderMax+borderBS ];
+        for ( int k = 0; k < borderMax; k++ ) {
+            tempborder[k]= border[k];
+            border[k].insertElem( NULL, fglmVector() );
+        }
+        delete [] border;
+        border= tempborder;
+#else
+        border= (borderElem *)omReallocSize( border, borderMax*sizeof( borderElem ), (borderMax + borderBS)*sizeof( borderElem ) );
+#endif
+        borderMax+= borderBS;
+    }
+#ifndef HAVE_EXPLICIT_CONSTR
+    border[borderSize].insertElem( m, v );
+#else
+    border[borderSize].borderElem( m, v );
+#endif
+    m= NULL;
+}
+
+fglmSelem
+fglmSdata::nextCandidate()
+{
+    fglmSelem result = nlist.getFirst();
+    nlist.removeFirst();
+    return result;
+}
+
+//     Multiplies basis[basisSize] with all ringvariables and inserts the new monomials
+//      into the list of candidates, according to the given order. If a monomial already
+//      exists, then "insertions" and "divisors" are updated.
+//     Assumes that ringvar(varperm[k]) < ringvar(varperm[l]) for k > l
+void
+fglmSdata::updateCandidates()
+{
+    ListIterator<fglmSelem> list = nlist;
+    fglmASSERT( basisSize > 0 && basisSize < basisMax, "Error(1) in fglmSdata::updateCandidates - wrong bassSize" );
+    poly m = basis[basisSize];
+    poly newmonom = NULL;
+    int k = pVariables;
+    BOOLEAN done = FALSE;
+    int state = 0;
+    while ( k >= 1 ) {
+        newmonom = pCopy( m );
+        pIncrExp( newmonom, varpermutation[k] );
+        pSetm( newmonom );
+        done= FALSE;
+        while ( list.hasItem() && (done == FALSE) ) {
+            if ( (state= pCmp( list.getItem().monom, newmonom )) < 0 )
+                list++;
+            else done= TRUE;
+        }
+        if ( done == FALSE ) {
+            nlist.append( fglmSelem( newmonom, k ) );
+            break;
+        }
+        if ( state == 0 ) {
+            list.getItem().newDivisor( k );
+            pDeleteLm(&newmonom);
+        }
+        else {
+            list.insert( fglmSelem( newmonom, k ) );
+        }
+        k--;
+    }
+    while ( --k >= 1 ) {
+        newmonom= pCopy( m ); // HIER
+        pIncrExp( newmonom, varpermutation[k] );
+        pSetm( newmonom );
+        nlist.append( fglmSelem( newmonom, k ) );
+    }
+}
+
+//     if p == pHead( (theIdeal->m)[k] ) return k, 0 otherwise
+//     (Assumes that pLmEqual just checks the leading monomials without
+//      coefficients.)
+int
+fglmSdata::getEdgeNumber( const poly m ) const
+{
+    for ( int k = idelems; k > 0; k-- )
+        if ( pLmEqual( m, (theIdeal->m)[k-1] ) )
+            return k;
+    return 0;
+}
+
+//     Returns the fglmVector v, s.t.
+//        p = v[1]*basis(1) + .. + v[basisSize]*basis(basisSize)
+//     So the size of v depends on the current size of the basis.
+//     Assumes that such an representation exists, i.e. all monoms in p have to be
+//      smaller than basis[basisSize] and that basis[k] < basis[l] for k < l.
+fglmVector
+fglmSdata::getVectorRep( const poly p )
+{
+    fglmVector temp( basisSize );
+    poly m = p;
+    int num = basisSize;
+    while ( m != NULL ) {
+        int comp = pCmp( m, basis[num] );
+        if ( comp == 0 ) {
+            fglmASSERT( num > 0, "Error(1) in fglmSdata::getVectorRep" );
+            number newelem = nCopy( pGetCoeff( m ) );
+            temp.setelem( num, newelem );
+            num--;
+            pIter( m );
+        }
+        else {
+            if ( comp < 0 ) {
+                num--;
+            }
+            else {
+                // This is the place where we can detect if the sourceIdeal
+                // is not reduced. In this case m is not in basis[]. Since basis[]
+                // is ordered this is the case, if and only if basis[i]<m
+                // and basis[j]>m for all j>i
+                _state= FALSE;
+                return temp;
+            }
+        }
+    }
+    return temp;
+}
+
+//     Searches through the border for a monomoial bm which devides m and returns
+//      its normalform in vector representation.
+//     var contains the number of the variable v, s.t. bm = m * v
+fglmVector
+fglmSdata::getBorderDiv( const poly m, int & var ) const
+{
+//     int num2 = borderSize;
+//     while ( num2 > 0 ) {
+//         poly temp = border[num2].monom;
+//         if ( pDivisibleBy( temp, m ) ) {
+//             poly divisor = pDivideM( m, temp );
+//             int var = pIsPurePower( divisor );
+//             if ( (var != 0) && (pGetCoeff( divisor, var ) == 1) ) {
+//                 Print( "poly %s divides poly %s", pString( temp ), pString( m ) );
+//             }
+//         }
+//         num2--;
+//     }
+    int num = borderSize;
+    while ( num > 0 ) {
+        poly temp = border[num].monom;
+        if ( pDivisibleBy( temp, m ) ) {
+            var = pVariables;
+            while ( var > 0 ) {
+                if ( (pGetExp( m, var ) - pGetExp( temp, var )) == 1 )
+                    return border[num].nf;
+                var--;
+            }
+        }
+        num--;
+    }
+    return fglmVector();
+}
+
+void
+internalCalculateFunctionals( const ideal & theIdeal, idealFunctionals & l,
+			      fglmSdata & data )
+{
+
+    // insert pOne() into basis and update the workingList:
+    poly one = pOne();
+    data.newBasisElem( one );
+    data.updateCandidates();
+
+    STICKYPROT(".");
+    while ( data.candidatesLeft() == TRUE ) {
+        fglmSelem candidate = data.nextCandidate();
+        if ( candidate.isBasisOrEdge() == TRUE ) {
+            int edge = data.getEdgeNumber( candidate.monom );
+            if ( edge != 0 ) {
+                // now candidate is an edge, i.e. we know its normalform:
+                // NF(p) = - ( tail(p)/LC(p) )
+                poly nf = data.getSpanPoly( edge );
+                pNorm( nf );
+                pDeleteLm(&nf);  //. deletes the leadingmonomial
+                nf= pNeg( nf );
+                fglmVector nfv = data.getVectorRep( nf );
+                l.insertCols( candidate.divisors, nfv );
+                data.newBorderElem( candidate.monom, nfv );
+                pDelete( &nf );
+                STICKYPROT( "+" );
+            }
+            else {
+                int basis= data.newBasisElem( candidate.monom );
+                data.updateCandidates();
+                l.insertCols( candidate.divisors, basis );
+                STICKYPROT( "." );
+            }
+        }
+        else {
+            int var = 0;
+            fglmVector temp = data.getBorderDiv( candidate.monom, var );
+            fglmASSERT( var > 0, "this should never happen" );
+            fglmVector nfv = l.addCols( var, data.getBasisSize(), temp );
+            data.newBorderElem( candidate.monom, nfv );
+            l.insertCols( candidate.divisors, nfv );
+            STICKYPROT( "-" );
+        }
+        candidate.cleanup();
+    } //. while ( data.candidatesLeft() == TRUE )
+    l.endofConstruction();
+    STICKYPROT2( "\nvdim= %i\n", data.getBasisSize() );
+    return;
+}
+
+//     Calculates the defining Functionals for the ideal "theIdeal" and
+//     returns them in "l".
+//     The ideal has to be zero-dimensional and reduced and has to be a
+//     real subset of the polynomal ring.
+//     In any case it has to be zero-dimensional and minimal (check this
+//      via fglmIdealcheck). Any minimal but not reduced ideal is detected.
+//      In this case it returns FglmNotReduced.
+//     If the base domain is Q, the leading coefficients of the polys
+//     have to be in Z.
+//     returns TRUE if the result is valid, FALSE if theIdeal
+//      is not reduced.
+static BOOLEAN
+CalculateFunctionals( const ideal & theIdeal, idealFunctionals & l )
+{
+    fglmSdata data( theIdeal );
+    internalCalculateFunctionals( theIdeal, l, data );
+    return ( data.state() );
+}
+
+static BOOLEAN
+CalculateFunctionals( const ideal & theIdeal, idealFunctionals & l,
+		      poly & p, fglmVector & v )
+{
+    fglmSdata data( theIdeal );
+    internalCalculateFunctionals( theIdeal, l, data );
+    //    STICKYPROT("Calculating vector rep\n");
+    v = data.getVectorRep( p );
+    // if ( v.isZero() ) 
+    //   STICKYPROT("vectorrep is 0\n");
+    return ( data.state() );
+}
+
+// ============================================================
+//!      The new basis
+// ============================================================
+
+//     The declaration of class fglmDelem is found in fglm.h
+
+fglmDelem::fglmDelem( poly & m, fglmVector mv, int v ) : v( mv ), insertions( 0 ), var( v )
+{
+    monom= m;
+    m= NULL;
+    for ( int k = pVariables; k > 0; k-- )
+        if ( pGetExp( monom, k ) > 0 )
+            insertions++;
+    // Wir gehen davon aus, dass ein fglmDelem direkt bei der Erzeugung
+    // auch in eine Liste eingefuegt wird. Daher wird hier automatisch
+    // newDivisor aufgerufen ( v teilt ja m )
+    newDivisor();
+}
+
+void
+fglmDelem::cleanup()
+{
+    if ( monom != NULL ) {
+        pDeleteLm(&monom);
+    }
+}
+
+class oldGaussElem
+{
+public:
+    fglmVector v;
+    fglmVector p;
+    number pdenom;
+    number fac;
+
+#ifndef HAVE_EXPLICIT_CONSTR
+    oldGaussElem() : v(), p(), pdenom( NULL ), fac( NULL ) {}
+#endif
+    oldGaussElem( const fglmVector newv, const fglmVector newp, number & newpdenom, number & newfac ) : v( newv ), p( newp ), pdenom( newpdenom ), fac( newfac )
+    {
+        newpdenom= NULL;
+        newfac= NULL;
+    }
+    ~oldGaussElem();
+#ifndef HAVE_EXPLICIT_CONSTR
+    void insertElem( const fglmVector newv, const fglmVector newp, number & newpdenom, number & newfac )
+    {
+        v= newv;
+        p= newp;
+        pdenom= newpdenom;
+        fac= newfac;
+        newpdenom= NULL;
+        newfac= NULL;
+    }
+#endif
+};
+
+oldGaussElem::~oldGaussElem()
+{
+    nDelete( & fac );
+    nDelete( & pdenom );
+}
+
+
+class fglmDdata
+{
+private:
+    int dimen;
+    oldGaussElem * gauss;
+    BOOLEAN * isPivot;  // [1]..[dimen]
+    int * perm;  // [1]..[dimen]
+    int basisSize;  //. the CURRENT basisSize, i.e. basisSize <= dimen
+    polyset basis;  // [1]..[dimen]. The monoms of the new Vectorspace-basis
+
+    int* varpermutation;
+
+    int groebnerBS;
+    int groebnerSize;
+    ideal destId;
+
+    List<fglmDelem> nlist;
+public:
+    fglmDdata( int dimension );
+    ~fglmDdata();
+
+    int getBasisSize() const { return basisSize; }
+    BOOLEAN candidatesLeft() const { return ( nlist.isEmpty() ? FALSE : TRUE ); }
+    fglmDelem nextCandidate();
+    void newBasisElem( poly & m, fglmVector v, fglmVector p, number & denom );
+    void updateCandidates( poly m, const fglmVector v );
+    void newGroebnerPoly( fglmVector & v, poly & p );
+    void gaussreduce( fglmVector & v, fglmVector & p, number & denom );
+    ideal buildIdeal()
+    {
+        idSkipZeroes( destId );
+        return destId;
+    }
+};
+
+fglmDdata::fglmDdata( int dimension )
+{
+    int k;
+    dimen= dimension;
+    basisSize= 0;
+    //. All arrays run from [1]..[dimen], thus omAlloc( dimen + 1 )!
+#ifndef HAVE_EXPLICIT_CONSTR
+    gauss= new oldGaussElem[ dimen+1 ];
+#else
+    gauss= (oldGaussElem *)omAlloc( (dimen+1)*sizeof( oldGaussElem ) );
+#endif
+    isPivot= (BOOLEAN *)omAlloc( (dimen+1)*sizeof( BOOLEAN ) );
+    for ( k= dimen; k > 0; k-- ) isPivot[k]= FALSE;
+    perm= (int *)omAlloc( (dimen+1)*sizeof( int ) );
+    basis= (polyset)omAlloc( (dimen+1)*sizeof( poly ) );
+    varpermutation = (int*)omAlloc( (pVariables+1)*sizeof(int) );
+    // Sort ring variables by increasing values (because of weighted orderings)
+    ideal perm = idMaxIdeal(1);
+    intvec *iv = idSort(perm,TRUE);
+    idDelete(&perm);
+    for(int i = pVariables; i > 0; i--) varpermutation[pVariables+1-i] = (*iv)[i-1];
+    delete iv;
+
+    groebnerBS= 16;
+    groebnerSize= 0;
+    destId= idInit( groebnerBS, 1 );
+}
+
+fglmDdata::~fglmDdata()
+{
+  // STICKYPROT2("dimen= %i", dimen);
+  // STICKYPROT2("basisSize= %i", basisSize);
+  //    fglmASSERT( dimen == basisSize, "Es wurden nicht alle BasisElemente gefunden!" );
+    int k;
+#ifndef HAVE_EXPLICIT_CONSTR
+    delete [] gauss;
+#else
+    // use basisSize instead of dimen because of fglmquot!
+    for ( k= basisSize; k > 0; k-- )
+        gauss[k].~oldGaussElem();
+    omFreeSize( (ADDRESS)gauss, (dimen+1)*sizeof( oldGaussElem ) );
+#endif
+    omFreeSize( (ADDRESS)isPivot, (dimen+1)*sizeof( BOOLEAN ) );
+    omFreeSize( (ADDRESS)perm, (dimen+1)*sizeof( int ) );
+    // use basisSize instead of dimen because of fglmquot!
+    //. Remember: There is no poly in basis[0], thus k > 0
+    for ( k= basisSize; k > 0; k-- )
+        pLmDelete( basis[k]);
+    omFreeSize( (ADDRESS)basis, (dimen+1)*sizeof( poly ) );
+    omFreeSize( (ADDRESS)varpermutation, (pVariables+1)*sizeof(int) );
+}
+
+fglmDelem
+fglmDdata::nextCandidate()
+{
+    fglmDelem result = nlist.getFirst();
+    nlist.removeFirst();
+    return result;
+}
+
+void
+fglmDdata::newBasisElem( poly & m, fglmVector v, fglmVector p, number & denom )
+{
+// inserts m as a new basis monom. m is NOT copied but directly inserted.
+// returns m=NULL to indicate, that now basis is oweing m.
+    basisSize++;
+    basis[basisSize]= m;
+    m= NULL;
+    int k= 1;
+    while ( nIsZero(v.getconstelem(k)) || isPivot[k] ) {
+        k++;
+    }
+    fglmASSERT( k <= dimen, "Error(1) in fglmDdata::pivot-search");
+    number pivot= v.getconstelem( k );
+    int pivotcol = k;
+    k++;
+    while ( k <= dimen ) {
+        if ( ! nIsZero( v.getconstelem(k) ) && ! isPivot[k] ) {
+            if ( nGreater( v.getconstelem( k ), pivot ) ) {
+                pivot= v.getconstelem( k );
+                pivotcol= k;
+            }
+        }
+        k++;
+    }
+    fglmASSERT( ! nIsZero( pivot ), "Error(2) fglmDdata::Pivotelement ist Null" );
+    isPivot[ pivotcol ]= TRUE;
+    perm[basisSize]= pivotcol;
+
+    pivot= nCopy( v.getconstelem( pivotcol ) );
+#ifndef HAVE_EXPLICIT_CONSTR
+    gauss[basisSize].insertElem( v, p, denom, pivot );
+#else
+    gauss[basisSize].oldGaussElem( v, p, denom, pivot );
+#endif
+}
+
+void
+fglmDdata::updateCandidates( poly m, const fglmVector v )
+{
+    ListIterator<fglmDelem> list = nlist;
+    poly newmonom = NULL;
+    int k = pVariables;
+    BOOLEAN done = FALSE;
+    int state = 0;
+    while ( k >= 1 ) {
+        newmonom = pCopy( m );
+        pIncrExp( newmonom, varpermutation[k] );
+        pSetm( newmonom );
+        done= FALSE;
+        while ( list.hasItem() && (done == FALSE) ) {
+            if ( (state= pCmp( list.getItem().monom, newmonom )) < 0 )
+                list++;
+            else done= TRUE;
+        }
+        if ( done == FALSE ) {
+            nlist.append( fglmDelem( newmonom, v, k ) );
+            break;
+        }
+        if ( state == 0 ) {
+            list.getItem().newDivisor();
+            pDeleteLm( & newmonom );
+        }
+        else {
+            list.insert( fglmDelem( newmonom, v, k ) );
+        }
+        k--;
+    }
+    while ( --k >= 1 ) {
+        newmonom= pCopy( m );
+        pIncrExp( newmonom, varpermutation[k] );
+        pSetm( newmonom );
+        nlist.append( fglmDelem( newmonom, v, k ) );
+    }
+}
+
+void
+fglmDdata::newGroebnerPoly( fglmVector & p, poly & m )
+// Inserts gp = p[1]*basis(1)+..+p[basisSize]*basis(basisSize)+p[basisSize+1]*m as
+//  a new groebner polynomial for the ideal.
+// All elements (monomials and coefficients) of gp are copied, instead of m.
+// Assumes that p.length() == basisSize+1.
+{
+    //. Baue das Polynom von oben nach unten:
+    fglmASSERT( p.size() == basisSize+1, "GP::newGroebnerPoly: p has wrong size" );
+    int k;
+    poly result = m;
+    poly temp = result;
+    m= NULL;
+    if ( nGetChar() > 0 ) {
+        number lead = nCopy( p.getconstelem( basisSize+1 ) );
+        p /= lead;
+        nDelete( & lead );
+    }
+    if ( nGetChar() == 0 ) {
+        number gcd= p.gcd();
+        fglmASSERT( ! nIsZero( gcd ), "FATAL: gcd and thus p is zero" );
+        if ( ! nIsOne( gcd ) )
+            p /= gcd;
+        nDelete( & gcd );
+    }
+    pSetCoeff( result, nCopy( p.getconstelem( basisSize+1 ) ) );
+    for ( k= basisSize; k > 0; k-- ) {
+        if ( ! nIsZero( p.getconstelem( k ) ) ) {
+            temp->next= pCopy( basis[k] );
+            pIter( temp );
+            pSetCoeff( temp, nCopy( p.getconstelem( k ) ) );
+        }
+    }
+    pSetm( result );
+    if ( ! nGreaterZero( pGetCoeff( result ) ) ) result= pNeg( result );
+    if ( groebnerSize == IDELEMS( destId ) ) {
+        pEnlargeSet( & destId->m, IDELEMS( destId ), groebnerBS );
+        IDELEMS( destId )+= groebnerBS;
+    }
+    (destId->m)[groebnerSize]= result;
+    groebnerSize++;
+}
+
+void
+fglmDdata::gaussreduce( fglmVector & v, fglmVector & p, number & pdenom )
+{
+    int k;
+    number fac1, fac2;
+    number temp;
+    fglmASSERT( pdenom == NULL, "pdenom in gaussreduce should be NULL" );
+    pdenom= nInit( 1 );
+    number vdenom = v.clearDenom();
+    if ( ! nIsOne( vdenom ) && ! nIsZero( vdenom ) ) {
+        p.setelem( p.size(), vdenom );
+    }
+    else {
+        nDelete( &vdenom );
+    }
+    number gcd = v.gcd();
+    if ( ! nIsOne( gcd ) && ! nIsZero( gcd ) ) {
+        v /= gcd;
+        number temp= nMult( pdenom, gcd );
+        nDelete( &pdenom );
+        pdenom= temp;
+    }
+    nDelete( & gcd );
+
+    for ( k= 1; k <= basisSize; k++ ) {
+
+        if ( ! v.elemIsZero( perm[k] ) ) {
+            fac1= gauss[k].fac;
+            fac2= nCopy( v.getconstelem( perm[k] ) );
+            v.nihilate( fac1, fac2, gauss[k].v );
+            fac1= nMult( fac1, gauss[k].pdenom );
+            temp= nMult( fac2, pdenom );
+            nDelete( &fac2 );
+            fac2= temp;
+              p.nihilate( fac1, fac2, gauss[k].p );
+            temp= nMult( pdenom, gauss[k].pdenom );
+            nDelete( &pdenom );
+            pdenom= temp;
+
+            nDelete( & fac1 );
+            nDelete( & fac2 );
+            number gcd = v.gcd();
+            if ( ! nIsOne( gcd ) && ! nIsZero( gcd ) ) {
+                v /= gcd;
+                number temp= nMult( pdenom, gcd );
+                nDelete( &pdenom );
+                pdenom= temp;
+            }
+            nDelete( & gcd );
+            gcd= p.gcd();
+            temp= nGcd( pdenom, gcd, currRing );
+            nDelete( &gcd );
+            gcd= temp;
+            if ( ! nIsZero( gcd ) && ! nIsOne( gcd ) ) {
+                p /= gcd;
+                temp= nDiv( pdenom, gcd );
+                nDelete( & pdenom );
+                pdenom= temp;
+                nNormalize( pdenom );
+            }
+            nDelete( & gcd );
+        }
+    }
+}
+
+static ideal
+GroebnerViaFunctionals( const idealFunctionals & l,
+			fglmVector iv = fglmVector() )
+// If iv is zero, calculates the groebnerBasis for the ideal which is
+// defined by l.
+// If iv is not zero, then the groebnerBasis if i:p is calculated where
+// i is defined by l and iv is the vector-representation of nf(p) wrt. i
+// The dimension of l has to be finite.
+// The result is in reduced form.
+{
+    fglmDdata data( l.dimen() );
+
+    // insert pOne() and update workinglist according to iv:
+    fglmVector initv;
+    if ( iv.isZero() ) {
+      // STICKYPROT("initv is zero\n");
+      initv = fglmVector( l.dimen(), 1 );
+    }
+    else {
+      // STICKYPROT("initv is not zero\n");
+      initv = iv;
+    }
+      
+    poly one = pOne();
+    data.updateCandidates( one, initv );
+    number nOne = nInit( 1 );
+    data.newBasisElem( one, initv, fglmVector( 1, 1 ), nOne );
+    STICKYPROT( "." );
+    while ( data.candidatesLeft() == TRUE ) {
+        fglmDelem candidate = data.nextCandidate();
+        if ( candidate.isBasisOrEdge() == TRUE ) {
+            // Now we have the chance to find a new groebner polynomial
+
+            // v is the vector-representation of candidate.monom
+            // some elements of v are zeroed in data.gaussreduce(). Which
+            // ones and how this was done is stored in p.
+            // originalV containes the unchanged v, which is later inserted
+            // into the working list (via data.updateCandidates().
+            fglmVector v = l.multiply( candidate.v, candidate.var );
+            fglmVector originalV = v;
+            fglmVector p( data.getBasisSize()+1, data.getBasisSize()+1 );
+            number pdenom = NULL;
+            data.gaussreduce( v, p, pdenom );
+            if ( v.isZero() ) {
+                // Now v is linear dependend to the already found basis elements.
+                // This means that v (rsp. candidate.monom) is the leading
+                // monomial of the next groebner-basis polynomial.
+                data.newGroebnerPoly( p, candidate.monom );
+                nDelete( & pdenom );
+                STICKYPROT( "+" );
+            }
+            else {
+                // no linear dependence could be found, so v ( rsp. monom )
+                // is a basis monomial. We store the zeroed version ( i.e. v
+                // and not originalV ) as well as p, the denomiator and all
+                // the other stuff.
+                // erst updateCandidates, dann newBasisELem!!!
+                data.updateCandidates( candidate.monom, originalV );
+                data.newBasisElem( candidate.monom, v, p, pdenom );
+                STICKYPROT( "." );
+            }
+        }
+        else {
+            STICKYPROT( "-" );
+            candidate.cleanup();
+        }
+    }  //. while data.candidatesLeft()
+    STICKYPROT( "\n" );
+    return ( data.buildIdeal() );
+}
+//<-
+
+static ideal
+FindUnivariatePolys( const idealFunctionals & l )
+{
+    fglmVector v;
+    fglmVector p;
+    ideal destIdeal = idInit( pVariables, 1 );
+
+    int i;
+    BOOLEAN isZero;
+    for ( i= 1; i <= pVariables; i++ ) {
+        // main loop
+        STICKYPROT2( "(%i)", i );
+        gaussReducer gauss( l.dimen() );
+        isZero= FALSE;
+        v= fglmVector( l.dimen(), 1 );
+        while ( isZero == FALSE ) {
+            if ( (isZero= gauss.reduce( v )) == TRUE ) {
+                STICKYPROT( "+" );
+                p= gauss.getDependence();
+                number gcd= p.gcd();
+                if ( ! nIsOne( gcd ) ) {
+                    p /= gcd;
+                }
+                nDelete( & gcd );
+                int k;
+                poly temp = NULL;
+                poly result;
+                for ( k= p.size(); k > 0; k-- ) {
+                    number n = nCopy( p.getconstelem( k ) );
+                    if ( ! nIsZero( n ) ) {
+                        if ( temp == NULL ) {
+                            result= pOne();
+                            temp= result;
+                        }
+                        else {
+                            temp->next= pOne();
+                            pIter( temp );
+                        }
+                        pSetCoeff( temp, n );
+                        pSetExp( temp, i, k-1 );
+                        pSetm( temp );
+                    }
+                }
+                if ( ! nGreaterZero( pGetCoeff( result ) ) ) result= pNeg( result );
+                (destIdeal->m)[i-1]= result;
+            }
+            else {
+                STICKYPROT( "." );
+                gauss.store();
+                v= l.multiply( v, i );
+            }
+        }
+    }
+    STICKYPROT( "\n" );
+    return destIdeal;
+}
+
+// for a descritption of the parameters see fglm.h
+BOOLEAN
+fglmzero( idhdl sourceRingHdl, ideal & sourceIdeal, idhdl destRingHdl, ideal & destIdeal, BOOLEAN switchBack, BOOLEAN deleteIdeal )
+{
+    idhdl initialRingHdl = currRingHdl;
+    BOOLEAN fglmok;
+
+    if ( currRingHdl != sourceRingHdl )
+        rSetHdl( sourceRingHdl );
+    idealFunctionals L( 100, pVariables );
+    fglmok = CalculateFunctionals( sourceIdeal, L );
+    if ( deleteIdeal == TRUE )
+        idDelete( & sourceIdeal );
+    rSetHdl( destRingHdl );
+    if ( fglmok == TRUE ) {
+        L.map( IDRING( sourceRingHdl ) );
+        destIdeal= GroebnerViaFunctionals( L );
+    }
+    if ( (switchBack == TRUE) && (currRingHdl != initialRingHdl) )
+        rSetHdl( initialRingHdl );
+    return fglmok;
+}
+
+BOOLEAN
+fglmquot( ideal sourceIdeal, poly quot, ideal & destIdeal)
+{
+    BOOLEAN fglmok;
+    fglmVector v;
+
+    idealFunctionals L( 100, pVariables );
+    // STICKYPROT("calculating normal form\n");
+    // poly p = kNF( sourceIdeal, currRing->qideal, quot );
+    // STICKYPROT("calculating functionals\n");
+    fglmok = CalculateFunctionals( sourceIdeal, L, quot, v );
+    if ( fglmok == TRUE ) {
+      // STICKYPROT("calculating groebner basis\n");
+        destIdeal= GroebnerViaFunctionals( L, v );
+    }
+    return fglmok;
+}
+
+BOOLEAN
+FindUnivariateWrapper( ideal source, ideal & destIdeal )
+{
+    BOOLEAN fglmok;
+
+    idealFunctionals L( 100, pVariables );
+    fglmok = CalculateFunctionals( source, L );
+    if ( fglmok == TRUE ) {
+        destIdeal= FindUnivariatePolys( L );
+        return TRUE;
+    }
+    else
+        return FALSE;
+}
+
+
+#endif
+
+// ----------------------------------------------------------------------------
+// Local Variables: ***
+// compile-command: "make Singular" ***
+// page-delimiter: "^\\(
+\\|//!\\)" ***
+// fold-internal-margins: nil ***
+// End: ***
Index: kernel/gccversion.sh
===================================================================
--- kernel/gccversion.sh	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/gccversion.sh	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# FILE:    gccversion
+# USAGE:   gccversion
+# PURPOSE: prints to stdout the gcc version type
+# AUTHOR:  hannes
+# CREATED: May 2003
+#
+#####################################################
+
+if test x$CC = x
+then
+  CC=cc
+fi
+cat >tmp.c <<EOF
+int main() {
+#ifdef __GNUC__
+char *p=__VERSION__;
+if (p[0]=='2') printf("gcc2\n");
+else if (p[0]=='3') printf("gcc3\n");
+else printf("gcc_unknown\n");
+#else
+printf("unknown\n");
+#endif
+exit(0); }
+EOF
+$CC tmp.c
+if test -e ./a.out; then
+  ./a.out
+  /bin/rm -f a.out tmp.c
+elif test -e a.exe; then
+  ./a.exe
+  /bin/rm -f tmp.c a.exe
+else
+  echo run_unknown
+fi
Index: kernel/gnumpc.cc
===================================================================
--- kernel/gnumpc.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/gnumpc.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,451 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: gnumpc.cc,v 1.1.1.1 2003-10-06 12:15:53 Singular Exp $ */
+/*
+* ABSTRACT: computations with GMP complex floating-point numbers
+*
+* ngc == number gnu complex
+*/
+
+#include "mod2.h"
+#include "structs.h"
+#include "febase.h"
+#include "omalloc.h"
+#include "numbers.h"
+#include "longrat.h"
+#include "modulop.h"
+#include "gnumpc.h"
+#include "gnumpfl.h"
+#include "mpr_complex.h"
+
+extern size_t gmp_output_digits;
+
+
+static number ngcMapQ(number from)
+{
+  if ( from != NULL )
+  {
+    gmp_complex *res=new gmp_complex(numberFieldToFloat(from,QTOF));
+    return (number)res;
+  }
+  else
+    return NULL;
+}
+union nf
+{
+  float _f;
+  number _n;
+  nf(float f) {_f = f;}
+  nf(number n) {_n = n;}
+  float F() const {return _f;}
+  number N() const {return _n;}
+};
+static number ngcMapLongR(number from)
+{
+  if ( from != NULL )
+  {
+    gmp_complex *res=new gmp_complex(*((gmp_float *)from));
+    return (number)res;
+  }
+  else
+    return NULL;
+}
+static number ngcMapR(number from)
+{
+  if ( from != NULL )
+  {
+    gmp_complex *res=new gmp_complex((double)nf(from).F());
+    return (number)res;
+  }
+  else
+    return NULL;
+}
+static number ngcMapP(number from)
+{
+  if ( from != NULL)
+    return ngcInit(npInt(from));
+  else
+    return NULL;
+}
+
+nMapFunc ngcSetMap(ring src,ring dst)
+{
+  if(rField_is_Q(src))
+  {
+    return ngcMapQ;
+  }
+  if (rField_is_long_R(src))
+  {
+    return ngcMapLongR;
+  }
+  if (rField_is_long_C(src))
+  {
+    return ngcCopy;
+  }
+  if(rField_is_R(src))
+  {
+    return ngcMapR;
+  }
+  if (rField_is_Zp(src))
+  {
+    return ngcMapP;
+  }
+  return NULL;
+}
+
+number   ngcPar(int i)
+{
+  gmp_complex* n= new gmp_complex( (long)0, (long)1 );
+  return (number)n;
+}
+
+void ngcNew (number * r)
+{
+  *r=NULL;
+}
+
+/*2
+* n := i
+*/
+number ngcInit (int i)
+{
+  gmp_complex* n= NULL;
+  if ( i != 0 )
+  {
+    n= new gmp_complex( (long)i, (long)0 );
+  }
+  return (number)n;
+}
+
+/*2
+* convert number to int
+*/
+int ngcInt(number &i)
+{
+  if ( i == NULL ) return 0;
+  return (int)((gmp_complex*)i)->real();
+}
+
+/*2
+* delete a
+*/
+void ngcDelete (number * a, const ring r)
+{
+  if ( *a != NULL ) {
+    delete *(gmp_complex**)a;
+    *a=NULL;
+  }
+}
+
+/*2
+* copy a to b
+*/
+number ngcCopy(number a)
+{
+  gmp_complex* b= NULL;
+  if ( a !=  NULL )
+  {
+    b= new gmp_complex( *(gmp_complex*)a );
+  }
+  return (number)b;
+}
+number ngc_Copy(number a, ring r)
+{
+  gmp_complex* b= NULL;
+  if ( a !=  NULL )
+  {
+    b= new gmp_complex( *(gmp_complex*)a );
+  }
+  return (number)b;
+}
+
+/*2
+* za:= - za
+*/
+number ngcNeg (number a)
+{
+  if ( a == NULL ) return NULL;
+  number m1=nInit(-1);
+  a=ngcMult(m1,a);
+  return (number)a;
+}
+
+/*
+* 1/a
+*/
+number ngcInvers(number a)
+{
+  gmp_complex* r= NULL;
+  if ( (a==NULL) /*|| ((gmp_complex*)a)->isZero()*/ )
+  {
+    WerrorS("div. 1/0");
+  }
+  else
+  {
+    r= new gmp_complex( (gmp_complex)1 / (*(gmp_complex*)a) );
+  }
+  return (number)r;
+}
+
+/*2
+* u:= a + b
+*/
+number ngcAdd (number a, number b)
+{
+  gmp_complex* r= NULL;
+  if ( a==NULL && b==NULL )
+  {
+    return NULL;
+  }
+  else if ( a == NULL )
+  {
+    r= new gmp_complex( *(gmp_complex*)b );
+  }
+  else if ( b == NULL )
+  {
+    r= new gmp_complex( *(gmp_complex*)a );
+  }
+  else
+  {
+    r= new gmp_complex( (*(gmp_complex*)a) + (*(gmp_complex*)b) );
+  }
+  return (number)r;
+}
+
+/*2
+* u:= a - b
+*/
+number ngcSub (number a, number b)
+{
+  gmp_complex* r= NULL;
+  if ( a==NULL && b==NULL )
+  {
+    return NULL;
+  }
+  else if ( a == NULL )
+  {
+    r= new gmp_complex( (*(gmp_complex*)b) );
+    r= (gmp_complex *)ngcNeg((number)r);
+  }
+  else if ( b == NULL )
+  {
+    r= new gmp_complex( *(gmp_complex*)a );
+  }
+  else
+  {
+    r= new gmp_complex( (*(gmp_complex*)a) - (*(gmp_complex*)b) );
+  }
+  return (number)r;
+}
+
+/*2
+* u := a * b
+*/
+number ngcMult (number a, number b)
+{
+  gmp_complex* r= NULL;
+  if ( a==NULL || b==NULL )
+  {
+    return NULL;
+  }
+  else
+  {
+    r= new gmp_complex( (*(gmp_complex*)a) * (*(gmp_complex*)b) );
+  }
+  return (number)r;
+}
+
+/*2
+* u := a / b
+*/
+number ngcDiv (number a, number b)
+{
+  if ( b==NULL /*|| ((gmp_float*)b)->isZero()*/ )
+  {
+    // a/0 = error
+    WerrorS("div. 1/0");
+    return NULL;
+  }
+  else if ( a==NULL )
+  {
+    // 0/b = 0
+    return NULL;
+  }
+  gmp_complex* r= new gmp_complex( (*(gmp_complex*)a) / (*(gmp_complex*)b) );
+  return (number)r;
+}
+
+/*2
+* u:= x ^ exp
+*/
+void ngcPower ( number x, int exp, number * u )
+{
+  if ( exp == 0 )
+  {
+    gmp_complex* n = new gmp_complex(1);
+    *u=(number)n;
+    return;
+  }
+  if ( exp == 1 )
+  {
+    nNew(u);
+    if ( x == NULL )
+    {
+      gmp_complex* n = new gmp_complex();
+      *u=(number)n;
+    }
+    else
+    {
+      gmp_complex* n = new gmp_complex();
+      *n= *(gmp_complex*)x;
+      *u=(number)n;
+    }
+    return;
+  }
+  ngcPower(x,exp-1,u);
+  gmp_complex *n=new gmp_complex();
+  *n=*(gmp_complex*)x;
+  *(gmp_complex*)(*u) *= *(gmp_complex*)n;
+  delete n;
+}
+
+BOOLEAN ngcIsZero (number a)
+{
+  if ( a == NULL ) return TRUE;
+  return ( ((gmp_complex*)a)->real().isZero() && ((gmp_complex*)a)->imag().isZero());
+}
+
+number ngcRePart(number a)
+{
+  if (((gmp_complex*)a)->real().isZero()) return NULL;
+  gmp_complex* n = new gmp_complex(((gmp_complex*)a)->real());
+  return (number)n;
+}
+
+number ngcImPart(number a)
+{
+  if (((gmp_complex*)a)->imag().isZero()) return NULL;
+  gmp_complex* n = new gmp_complex(((gmp_complex*)a)->imag());
+  return (number)n;
+}
+
+/*2
+* za >= 0 ?
+*/
+BOOLEAN ngcGreaterZero (number a)
+{
+  if ( a == NULL ) return TRUE;
+  if ( ! ((gmp_complex*)a)->imag().isZero() )
+    return ( abs( *(gmp_complex*)a).sign() >= 0 );
+  else
+    return ( ((gmp_complex*)a)->real().sign() >= 0 );
+}
+
+/*2
+* a > b ?
+*/
+BOOLEAN ngcGreater (number a, number b)
+{
+  if ( a==NULL )
+  {
+    return (((gmp_complex*)b)->real().sign() < 0);
+  }
+  if ( b==NULL )
+  {
+    return (((gmp_complex*)a)->real().sign() < 0);
+  }
+  return FALSE;
+}
+
+/*2
+* a = b ?
+*/
+BOOLEAN ngcEqual (number a, number b)
+{
+  if ( a == NULL && b == NULL )
+  {
+    return TRUE;
+  }
+  else if ( a == NULL || b == NULL )
+  {
+    return FALSE;
+  }
+  return ( (*(gmp_complex*)a) == (*(gmp_complex*)b) );
+}
+
+/*2
+* a == 1 ?
+*/
+BOOLEAN ngcIsOne (number a)
+{
+  if ( a == NULL ) return FALSE;
+  //return (((gmp_complex*)a)->real().isOne() && ((gmp_complex*)a)->imag().isZero());
+  return (((gmp_complex*)a)->real().isOne());
+}
+
+/*2
+* a == -1 ?
+*/
+BOOLEAN ngcIsMOne (number a)
+{
+  if ( a == NULL ) return FALSE;
+  //  return (((gmp_complex*)a)->real().isMOne() && ((gmp_complex*)a)->imag().isZero());
+  return (((gmp_complex*)a)->real().isMOne());
+}
+
+/*2
+* extracts the number a from s, returns the rest
+*/
+char * ngcRead (char * s, number * a)
+{
+  char *start= s;
+  if ((*s >= '0') && (*s <= '9'))
+  {
+    gmp_float *re=NULL;
+    s=ngfRead(s,(number *)&re);
+    gmp_complex *aa=new gmp_complex(*re);
+    *a=(number)aa;
+    delete re;
+  }
+  else if (strncmp(s,currRing->parameter[0],strlen(currRing->parameter[0]))==0)
+  {
+    s+=strlen(currRing->parameter[0]);
+    gmp_complex *aa=new gmp_complex((long)0,(long)1);
+    *a=(number)aa;
+  }
+  else
+  {
+    *a=(number) new gmp_complex((long)1);
+  }
+  return s;
+}
+
+/*2
+* write a floating point number
+*/
+void ngcWrite (number &a)
+{
+  if (a==NULL)
+    StringAppend("0");
+  else
+  {
+    char *out;
+    out= complexToStr(*(gmp_complex*)a,gmp_output_digits);
+    StringAppend(out);
+    //    omFreeSize((ADDRESS)out, (strlen(out)+1)* sizeof(char) );
+    omFree( (ADDRESS)out );
+  }
+}
+
+#ifdef LDEBUG
+BOOLEAN ngcDBTest(number a, char *f, int l)
+{
+  return TRUE;
+}
+#endif
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command: "make installg" ***
+// End: ***
Index: kernel/gnumpc.h
===================================================================
--- kernel/gnumpc.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/gnumpc.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,50 @@
+#ifndef GMPCOMPLEX_H
+#define GMPCOMPLEX_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: gnumpc.h,v 1.1.1.1 2003-10-06 12:15:53 Singular Exp $ */
+/*
+* ABSTRACT: computations with GMP floating-point numbers
+*/
+#include "structs.h"
+
+BOOLEAN  ngcGreaterZero(number za);      // !!! MAY NOT WORK AS EXPECTED !!!
+BOOLEAN  ngcGreater(number a, number b);
+BOOLEAN  ngcEqual(number a, number b);
+BOOLEAN  ngcIsOne(number a);
+BOOLEAN  ngcIsMOne(number a);
+BOOLEAN  ngcIsZero(number za);
+void     ngcNew(number *r);
+number   ngcInit(int i);
+int      ngcInt(number &n);
+number   ngcNeg(number za);
+number   ngcInvers(number a);
+number   ngcPar(int i);
+number   ngcAdd(number la, number li);
+number   ngcSub(number la, number li);
+number   ngcMult(number a, number b);
+number   ngcDiv(number a, number b);
+void     ngcPower(number x, int exp, number *lu);
+number   ngcCopy(number a);
+number   ngc_Copy(number a, ring r);
+char *   ngcRead (char *s, number *a);
+void     ngcWrite(number &a);
+number   ngcRePart(number a);
+number   ngcImPart(number a);
+
+
+#ifdef LDEBUG
+BOOLEAN  ngcDBTest(number a, char *f, int l);
+#endif
+void     ngcDelete(number *a, const ring r);
+
+nMapFunc  ngcSetMap(ring src, ring dst);
+
+#endif
+
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command: "make installg" ***
+// End: ***
Index: kernel/gnumpfl.cc
===================================================================
--- kernel/gnumpfl.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/gnumpfl.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,483 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: gnumpfl.cc,v 1.1.1.1 2003-10-06 12:15:53 Singular Exp $ */
+/*
+* ABSTRACT: computations with GMP floating-point numbers
+*
+* ngf == number gnu floats
+*/
+
+#include "mod2.h"
+#include "structs.h"
+#include "febase.h"
+#include "omalloc.h"
+#include "numbers.h"
+#include "modulop.h"
+#include "longrat.h"
+
+#include "gnumpfl.h"
+#include "mpr_complex.h"
+
+extern size_t gmp_output_digits;
+
+static number ngfMapP(number from)
+{
+  if ( from != NULL)
+    return ngfInit(npInt(from));
+  else
+    return NULL;
+}
+static number ngfMapQ(number from)
+{
+  if ( from != NULL )
+  {
+    gmp_float *res=new gmp_float(numberFieldToFloat(from,QTOF));
+    return (number)res;
+  }
+  else
+    return NULL;
+}
+union nf
+{
+  float _f;
+  number _n;
+  nf(float f) {_f = f;}
+  nf(number n) {_n = n;}
+  float F() const {return _f;}
+  number N() const {return _n;}
+};
+static number ngfMapR(number from)
+{
+  if ( from != NULL )
+  {
+    gmp_float *res=new gmp_float((double)nf(from).F());
+    return (number)res;
+  }
+  else
+    return NULL;
+}
+static number ngfMapC(number from)
+{
+  if ( (from != NULL) || ((gmp_complex*)from)->real().isZero() )
+  {
+    gmp_float *res=new gmp_float(((gmp_complex*)from)->real());
+    return (number)res;
+  }
+  else
+    return NULL;
+}
+
+nMapFunc ngfSetMap(ring src, ring dst)
+{
+  if (rField_is_Q(src))
+  {
+    return ngfMapQ;
+  }
+  if (rField_is_long_R(src))
+  {
+    return ngfCopy;
+  }
+  if (rField_is_R(src))
+  {
+    return ngfMapR;
+  }
+  if (rField_is_Zp(src))
+  {
+    return ngfMapP;
+  }
+  if (rField_is_long_C(src))
+  {
+    return ngfMapC;
+  }
+  return NULL;
+}
+
+void ngfNew (number * r)
+{
+  *r= NULL;
+}
+
+/*2
+* n := i
+*/
+number ngfInit (int i)
+{
+  gmp_float* n= NULL;
+  if ( i != 0 )
+  {
+    n= new gmp_float( (double)i );
+  }
+  return (number)n;
+}
+
+/*2
+* convert number to int
+*/
+int ngfInt(number &i)
+{
+  if ( i == NULL ) return 0;
+  return (int)*(gmp_float*)i;
+}
+
+/*2
+* delete a
+*/
+void ngfDelete (number * a, const ring r)
+{
+  if ( *a != NULL )
+  {
+    delete *(gmp_float**)a;
+    *a=NULL;
+  }
+}
+
+/*2
+* copy a to b
+*/
+number ngfCopy(number a)
+{
+  gmp_float* b= NULL;
+  if ( a !=  NULL )
+  {
+    b= new gmp_float( *(gmp_float*)a );
+  }
+  return (number)b;
+}
+
+number ngf_Copy(number a, ring r)
+{
+  gmp_float* b= NULL;
+  if ( a !=  NULL )
+  {
+    b= new gmp_float( *(gmp_float*)a );
+  }
+  return (number)b;
+}
+
+/*2
+* za:= - za
+*/
+number ngfNeg (number a)
+{
+  if ( a == NULL ) return NULL;
+  *(gmp_float*)a= -(*(gmp_float*)a);
+  return (number)a;
+}
+
+/*
+* 1/a
+*/
+number ngfInvers(number a)
+{
+  gmp_float* r= NULL;
+  if ( (a==NULL) /*|| ((gmp_float*)a)->isZero()*/ )
+  {
+    WerrorS("div. 1/0");
+  }
+  else
+  {
+    r= new gmp_float( (gmp_float)1 / (*(gmp_float*)a) );
+  }
+  return (number)r;
+}
+
+/*2
+* u:= a + b
+*/
+number ngfAdd (number a, number b)
+{
+  gmp_float* r= NULL;
+  if ( a==NULL && b==NULL )
+  {
+    return NULL;
+  }
+  else if ( a == NULL )
+  {
+    r= new gmp_float( *(gmp_float*)b );
+  }
+  else if ( b == NULL )
+  {
+    r= new gmp_float( *(gmp_float*)a );
+  }
+  else
+  {
+    r= new gmp_float( (*(gmp_float*)a) + (*(gmp_float*)b) );
+  }
+  return (number)r;
+}
+
+/*2
+* u:= a - b
+*/
+number ngfSub (number a, number b)
+{
+  gmp_float* r= NULL;
+  if ( a==NULL && b==NULL )
+  {
+    return NULL;
+  }
+  else if ( a == NULL )
+  {
+    r= new gmp_float( -(*(gmp_float*)b) );
+  }
+  else if ( b == NULL )
+  {
+    r= new gmp_float( *(gmp_float*)a );
+  }
+  else
+  {
+    r= new gmp_float( (*(gmp_float*)a) - (*(gmp_float*)b) );
+  }
+  return (number)r;
+}
+
+/*2
+* u := a * b
+*/
+number ngfMult (number a, number b)
+{
+  gmp_float* r= NULL;
+  if ( a==NULL || b==NULL )
+  {
+    return NULL;
+  }
+  else
+  {
+    r= new gmp_float( (*(gmp_float*)a) * (*(gmp_float*)b) );
+  }
+  return (number)r;
+}
+
+/*2
+* u := a / b
+*/
+number ngfDiv (number a, number b)
+{
+  if ( b==NULL /*|| ((gmp_float*)b)->isZero()*/ )
+  {
+    // a/0 = error
+    WerrorS("div. 1/0");
+    return NULL;
+  }
+  else if ( a==NULL )
+  {
+    // 0/b = 0
+    return NULL;
+  }
+  gmp_float* r= new gmp_float( (*(gmp_float*)a) / (*(gmp_float*)b) );
+  return (number)r;
+}
+
+/*2
+* u:= x ^ exp
+*/
+void ngfPower ( number x, int exp, number * u )
+{
+  if ( exp == 0 )
+  {
+    gmp_float* n = new gmp_float(1);
+    *u=(number)n;
+    return;
+  }
+  if ( exp == 1 )
+  {
+    nNew(u);
+    if ( x == NULL )
+    {
+      gmp_float* n = new gmp_float();
+      *u=(number)n;
+    }
+    else
+    {
+      gmp_float* n = new gmp_float();
+      *n= *(gmp_float*)x;
+      *u=(number)n;
+    }
+    return;
+  }
+  ngfPower(x,exp-1,u);
+
+  gmp_float *n=new gmp_float();
+  *n=*(gmp_float*)x;
+  *(gmp_float*)(*u) *= *(gmp_float*)n;
+  delete (gmp_float*)n;
+}
+
+BOOLEAN ngfIsZero (number a)
+{
+  if ( a == NULL ) return TRUE;
+  return ( ((gmp_float*)a)->isZero() );
+}
+
+/*2
+* za >= 0 ?
+*/
+BOOLEAN ngfGreaterZero (number a)
+{
+  if ( a == NULL ) return TRUE;
+  return ( (*(gmp_float*)a) >= (gmp_float)0.0 );
+}
+
+/*2
+* a > b ?
+*/
+BOOLEAN ngfGreater (number a, number b)
+{
+  if ( a==NULL )
+  {
+    return (((gmp_float*)b)->sign() < 0);
+  }
+  if ( b==NULL )
+  {
+    return (((gmp_float*)a)->sign() > 0);
+  }
+  return ( (*(gmp_float*)a) > (*(gmp_float*)b) );
+}
+
+/*2
+* a = b ?
+*/
+BOOLEAN ngfEqual (number a, number b)
+{
+  if ( a == NULL && b == NULL )
+  {
+    return TRUE;
+  }
+  else if ( a == NULL || b == NULL )
+  {
+    return FALSE;
+  }
+  return ( (*(gmp_float*)a) == (*(gmp_float*)b) );
+}
+
+/*2
+* a == 1 ?
+*/
+BOOLEAN ngfIsOne (number a)
+{
+  if ( a == NULL ) return FALSE;
+  return ((gmp_float*)a)->isOne();
+}
+
+/*2
+* a == -1 ?
+*/
+BOOLEAN ngfIsMOne (number a)
+{
+  if ( a == NULL ) return FALSE;
+  return ((gmp_float*)a)->isMOne();
+}
+
+/*2
+* result =gcd(a,b)
+* dummy, returns 1
+*/
+number ngfGcd(number a, number b)
+{
+  gmp_float *result= new gmp_float( 1 );
+  return (number)result;
+}
+
+char * ngfEatFloatNExp( char * s )
+{
+  char *start= s;
+
+  // eat floats (mantissa) like:
+  //   0.394394993, 102.203003008,  .300303032
+  while ((*s >= '0' && *s <= '9')||(*s == '.')) s++;
+
+  // eat the exponent, starts with 'e' followed by '+', '-'
+  // and digits, like:
+  //   e-202, e+393
+  if ( (s != start) && (*s == 'e') && ((*(s+1) == '+') || (*(s+1) == '-')) )
+  {
+    s=s+2; // eat e and sign
+    while ((*s >= '0' && *s <= '9')) s++;
+  }
+
+  return s;
+}
+
+/*2
+* extracts the number a from s, returns the rest
+*/
+char * ngfRead (char * s, number * a)
+{
+  char *start= s;
+
+  //Print("%s\n",s);
+
+  s= ngfEatFloatNExp( s );
+
+  if (*s=='\0')  // 0
+  {
+    if ( *(gmp_float**)a == NULL ) (*(gmp_float**)a)= new gmp_float();
+    (*(gmp_float**)a)->setFromStr(start);
+  }
+  else if (s==start)  // 1
+  {
+    if ( *(gmp_float**)a != NULL )  delete (*(gmp_float**)a);
+    (*(gmp_float**)a)= new gmp_float(1);
+  }
+  else
+  {
+    gmp_float divisor(1.0);
+    char *start2=s;
+    if ( *s == '/' )
+    {
+      s++;
+      s= ngfEatFloatNExp( s );
+      if (s!= start2+1)
+      {
+        char tmp_c=*s;
+        *s='\0';
+        divisor.setFromStr(start2+1);
+        *s=tmp_c;
+      }
+      else
+      {
+        Werror("wrong long real format: %s",start2);
+      }
+    }
+    char c=*start2;
+    *start2='\0';
+    if ( *(gmp_float**)a == NULL ) (*(gmp_float**)a)= new gmp_float();
+    (*(gmp_float**)a)->setFromStr(start);
+    *start2=c;
+    (**(gmp_float**)a) /= divisor;
+  }
+
+  return s;
+}
+
+/*2
+* write a floating point number
+*/
+void ngfWrite (number &a)
+{
+  char *out;
+  if ( a != NULL )
+  {
+    out= floatToStr(*(gmp_float*)a,gmp_output_digits);
+    StringAppend(out);
+    //omFreeSize((ADDRESS)out, (strlen(out)+1)* sizeof(char) );
+    omFree( (ADDRESS)out );
+  }
+  else
+  {
+    StringAppend("0");
+  }
+}
+
+#ifdef LDEBUG
+BOOLEAN ngfDBTest(number a, char *f, int l)
+{
+  return TRUE;
+}
+#endif
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command: "make installg" ***
+// End: ***
Index: kernel/gnumpfl.h
===================================================================
--- kernel/gnumpfl.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/gnumpfl.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,41 @@
+#ifndef GMPFLOAT_H
+#define GMPFLOAT_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: gnumpfl.h,v 1.1.1.1 2003-10-06 12:15:53 Singular Exp $ */
+/*
+* ABSTRACT: computations with GMP floating-point numbers
+*/
+#include "structs.h"
+
+BOOLEAN  ngfGreaterZero(number za);
+BOOLEAN  ngfGreater(number a, number b);
+BOOLEAN  ngfEqual(number a, number b);
+BOOLEAN  ngfIsOne(number a);
+BOOLEAN  ngfIsMOne(number a);
+BOOLEAN  ngfIsZero(number za);
+void     ngfNew(number *r);
+number   ngfInit(int i);
+int      ngfInt(number &n);
+number   ngfNeg(number za);
+number   ngfInvers(number a);
+number   ngfAdd(number la, number li);
+number   ngfSub(number la, number li);
+number   ngfMult(number a, number b);
+number   ngfDiv(number a, number b);
+void     ngfPower(number x, int exp, number *lu);
+number   ngfCopy(number a);
+number   ngf_Copy(number a, ring r);
+char *   ngfRead (char *s, number *a);
+void     ngfWrite(number &a);
+
+#ifdef LDEBUG
+BOOLEAN  ngfDBTest(number a, char *f, int l);
+#endif
+void     ngfDelete(number *a, const ring r);
+
+nMapFunc  ngfSetMap(ring src, ring dst);
+
+void setGMPFloatDigits( size_t digits, size_t rest );
+#endif
Index: kernel/gr_kstd2.cc
===================================================================
--- kernel/gr_kstd2.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/gr_kstd2.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,922 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: gr_kstd2.cc,v 1.1.1.1 2003-10-06 12:15:53 Singular Exp $ */
+/*
+*  ABSTRACT -  Kernel: noncomm. alg. of Buchberger
+*/
+
+#include "mod2.h"
+#ifdef HAVE_PLURAL
+#include "omalloc.h"
+#include "polys.h"
+#include "ideals.h"
+#include "febase.h"
+#include "kutil.h"
+#include "kstd1.h"
+#include "khstd.h"
+//#include "spolys.h"
+#include "cntrlc.h"
+#include "weight.h"
+#include "ipid.h"
+#include "ipshell.h"
+#include "intvec.h"
+#include "tok.h"
+#include "gring.h"
+
+/*2
+* consider the part above syzComp:
+* (assume the polynomial comes from a syz computation)
+* - it is a constant term: return a copy of it
+* - else: return NULL
+*/
+static poly kFromInput(poly p,kStrategy strat)
+{
+  poly q=p;
+
+  if (pGetComp(q)>strat->syzComp) return NULL;
+  while ((q!=NULL) && (pGetComp(q)<=strat->syzComp)) pIter(q);
+  if (pIsConstantComp(q))
+    return pHead(q);
+  return NULL;
+}
+
+/*2
+*reduces h with elements from T choosing  the first possible
+* element in t with respect to the given pDivisibleBy
+*/
+int redGrFirst (LObject* h,kStrategy strat)
+{
+  int at,reddeg,d,i;
+  int pass = 0;
+  int j = 0;
+
+  d = pFDeg((*h).p)+(*h).ecart;
+  reddeg = strat->LazyDegree+d;
+  loop
+  {
+    if (j > strat->sl)
+    {
+      if (TEST_OPT_DEBUG) PrintLn();
+      return 0;
+    }
+    if (TEST_OPT_DEBUG) Print("%d",j);
+    if (pDivisibleBy(strat->S[j],(*h).p))
+    {
+      if (TEST_OPT_DEBUG) PrintS("+\n");
+      /*
+      * the polynomial to reduce with is;
+      * T[j].p
+      */
+      if (!TEST_OPT_INTSTRATEGY)
+        pNorm(strat->S[j]);
+      if (TEST_OPT_DEBUG)
+      {
+        wrp(h->p);
+        PrintS(" with ");
+        wrp(strat->S[j]);
+      }
+      (*h).p = nc_spGSpolyRed(strat->S[j],(*h).p, NULL, currRing);
+      //spSpolyRed(strat->T[j].p,(*h).p,strat->kNoether);
+
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS(" to ");
+        wrp(h->p);
+      }
+      if ((*h).p == NULL)
+      {
+        if (h->lcm!=NULL) p_LmFree((*h).lcm, currRing);
+        return 0;
+      }
+      if (TEST_OPT_INTSTRATEGY)
+      {
+        pCleardenom((*h).p);
+      }
+      /*computes the ecart*/
+      d = pLDeg((*h).p,&((*h).length));
+      (*h).FDeg=pFDeg((*h).p);
+      (*h).ecart = d-(*h).FDeg; /*pFDeg((*h).p);*/
+      if ((strat->syzComp!=0) && !strat->honey)
+      {
+        if ((strat->syzComp>0) && (pMinComp((*h).p) > strat->syzComp))
+        {
+          if (TEST_OPT_DEBUG) PrintS(" > sysComp\n");
+          return 0;
+        }
+      }
+      /*- try to reduce the s-polynomial -*/
+      pass++;
+      /*
+      *test whether the polynomial should go to the lazyset L
+      *-if the degree jumps
+      *-if the number of pre-defined reductions jumps
+      */
+      if ((strat->Ll >= 0)
+      && ((d >= reddeg) || (pass > strat->LazyPass))
+      && !strat->homog)
+      {
+        at = strat->posInL(strat->L,strat->Ll,h,strat);
+        if (at <= strat->Ll)
+        {
+          i=strat->sl+1;
+          do
+          {
+            i--;
+            if (i<0) return 0;
+          } while (!pDivisibleBy(strat->S[i],(*h).p));
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+          if (TEST_OPT_DEBUG) Print(" degree jumped; ->L%d\n",at);
+          (*h).p = NULL;
+          return 0;
+        }
+      }
+      if ((TEST_OPT_PROT) && (strat->Ll < 0) && (d >= reddeg))
+      {
+        reddeg = d+1;
+        Print(".%d",d);mflush();
+      }
+      j = 0;
+      if TEST_OPT_DEBUG PrintLn();
+    }
+    else
+    {
+      if (TEST_OPT_DEBUG) PrintS("-");
+      j++;
+    }
+  }
+}
+
+/*2
+*  reduction procedure for the homogeneous case
+*  and the case of a degree-ordering
+*/
+static int redHomog (LObject* h,kStrategy strat)
+{
+  if (strat->tl<0)
+  {
+    enterT((*h),strat);
+    return 1;
+  }
+
+  int j = 0;
+
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("red:");
+    wrp(h->p);
+    PrintS(" ");
+  }
+  loop
+  {
+    if (TEST_OPT_DEBUG) Print("%d",j);
+    if (pDivisibleBy(strat->S[j],(*h).p))
+    {
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("+\nwith ");
+        wrp(strat->S[j]);
+      }
+      /*- compute the s-polynomial -*/
+      (*h).p = nc_spGSpolyRed(strat->S[j],(*h).p,strat->kNoether,currRing);
+      if ((*h).p == NULL)
+      {
+        if (TEST_OPT_DEBUG) PrintS(" to 0\n");
+        if (h->lcm!=NULL) pLmFree((*h).lcm);
+        (*h).lcm=NULL;
+        return 0;
+      }
+/*
+*      else if (strat->syzComp)
+*      {
+*        if (pMinComp((*h).p) > strat->syzComp)
+*        {
+*          enterT((*h),strat);
+*          return;
+*        }
+*      }
+*/
+      /*- try to reduce the s-polynomial -*/
+      j = 0;
+    }
+    else
+    {
+      if (j >= strat->sl)
+      {
+        enterT((*h),strat);
+        return 1;
+      }
+      j++;
+    }
+  }
+}
+
+/*2
+*  reduction procedure for the homogeneous case
+*  and the case of a degree-ordering
+*/
+static int redHomog0 (LObject* h,kStrategy strat)
+{
+  if (strat->tl<0)
+  {
+    enterT((*h),strat);
+    return 0;
+  }
+
+  int j = 0;
+  int k = 0;
+
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("red:");
+    wrp(h->p);
+    PrintS(" ");
+  }
+  loop
+  {
+    if (TEST_OPT_DEBUG) Print("%d",j);
+    if (pDivisibleBy(strat->T[j].p,(*h).p))
+    {
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("+\nwith ");
+        wrp(strat->S[j]);
+      }
+      /*- compute the s-polynomial -*/
+      (*h).p = nc_spGSpolyRed(strat->T[j].p,(*h).p,strat->kNoether,currRing);
+      if ((*h).p == NULL)
+      {
+        if (TEST_OPT_DEBUG) PrintS(" to 0\n");
+        if (h->lcm!=NULL) pLmFree((*h).lcm);
+        (*h).lcm=NULL;
+        return 0;
+      }
+      else if (strat->syzComp!=0)
+      {
+        if ((strat->syzComp>0) && (pMinComp((*h).p) > strat->syzComp))
+        {
+          //pContent((*h).p);
+          pCleardenom((*h).p);// also does a pContent
+/*
+*         (*h).length=pLength0((*h).p);
+*/
+          enterT((*h),strat);
+          return 0;
+        }
+      }
+      /*- try to reduce the s-polynomial -*/
+      j = 0;
+    }
+    else
+    {
+      if (j >= strat->tl)
+      {
+        //pContent((*h).p);
+        pCleardenom((*h).p);// also does a pContent
+/*
+*       (*h).length=pLength0((*h).p);
+*/
+        enterT((*h),strat);
+        return 0;
+      }
+      j++;
+    }
+  }
+}
+
+/*2
+*  reduction procedure for the inhomogeneous case
+*  and not a degree-ordering
+*/
+static int redLazy (LObject* h,kStrategy strat)
+{
+  if (strat->tl<0)
+  {
+    enterT((*h),strat);
+    return 0;
+  }
+
+  int at,d,i;
+  int j = 0;
+  int pass = 0;
+  int reddeg = pFDeg((*h).p);
+
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("red:");
+    wrp(h->p);
+    PrintS(" ");
+  }
+  loop
+  {
+    if (TEST_OPT_DEBUG) Print("%d",j);
+    if (pDivisibleBy(strat->S[j],(*h).p))
+    {
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("+\nwith ");
+        wrp(strat->S[j]);
+      }
+      /*- compute the s-polynomial -*/
+      (*h).p = nc_spGSpolyRed(strat->S[j],(*h).p,strat->kNoether,currRing);
+      if ((*h).p == NULL)
+      {
+        if (TEST_OPT_DEBUG) PrintS(" to 0\n");
+        if (h->lcm!=NULL) pLmFree((*h).lcm);
+        (*h).lcm=NULL;
+        return 0;
+      }
+//      else if (strat->syzComp)
+//      {
+//        if ((strat->syzComp>0) && (pMinComp((*h).p) > strat->syzComp))
+//        {
+//          if (TEST_OPT_DEBUG) PrintS(" > syzComp\n");
+//          if (TEST_OPT_INTSTRATEGY) pContent(h->p);
+//          enterTBba((*h),strat->tl+1,strat);
+//          return;
+//        }
+//      }
+      else if (TEST_OPT_DEBUG)
+      {
+        PrintS("to:");
+        wrp((*h).p);
+        PrintLn();
+      }
+      /*- try to reduce the s-polynomial -*/
+      pass++;
+      d = pFDeg((*h).p);
+      if ((strat->Ll >= 0) && ((d > reddeg) || (pass > strat->LazyPass)))
+      {
+        at = posInL11(strat->L,strat->Ll,h,strat);
+        if (at <= strat->Ll)
+        {
+          i=strat->sl+1;
+          do
+          {
+            i--;
+            if (i<0)
+            {
+              enterT((*h),strat);
+              return 0;
+            }
+          }
+           while (!pDivisibleBy(strat->S[i],(*h).p));
+          if (TEST_OPT_DEBUG) Print(" ->L[%d]\n",at);
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+          (*h).p = NULL;
+          return 0;
+        }
+      }
+      else if ((TEST_OPT_PROT) && (strat->Ll < 0) && (d != reddeg))
+      {
+        Print(".%d",d);mflush();
+        reddeg = d;
+      }
+      j = 0;
+    }
+    else
+    {
+      if (TEST_OPT_DEBUG) PrintS("-");
+      if (j >= strat->sl)
+      {
+        if (TEST_OPT_DEBUG) PrintLn();
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          //pContent(h->p);
+          pCleardenom(h->p);// also does a pContent
+        }
+        enterT((*h),strat);
+        return 0;
+      }
+      j++;
+    }
+  }
+}
+
+/*2
+*  reduction procedure for the sugar-strategy (honey)
+* reduces h with elements from T choosing first possible
+* element in T with respect to the given ecart
+*/
+static int redHoney (LObject*  h,kStrategy strat)
+{
+  if (strat->tl<0)
+  {
+    enterT((*h),strat);
+    return 0;
+  }
+
+  poly pi;
+  int i,j,at,reddeg,d,pass,ei;
+
+  pass = j = 0;
+  d = reddeg = pFDeg((*h).p)+(*h).ecart;
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("red:");
+    wrp((*h).p);
+  }
+  loop
+  {
+    if (TEST_OPT_DEBUG) Print("%d",j);
+    if (pDivisibleBy(strat->T[j].p,(*h).p))
+    {
+      if (TEST_OPT_DEBUG) PrintS("+");
+      pi = strat->T[j].p;
+      ei = strat->T[j].ecart;
+      /*
+      * the polynomial to reduce with (up to the moment) is;
+      * pi with ecart ei
+      */
+      i = j;
+      loop
+      {
+        /*- takes the first possible with respect to ecart -*/
+        i++;
+        if (i > strat->tl)
+          break;
+        if ((!BTEST1(20)) && (ei <= (*h).ecart))
+          break;
+        if (TEST_OPT_DEBUG) Print("%d",i);
+        if ((strat->T[i].ecart < ei) && pDivisibleBy(strat->T[i].p,(*h).p))
+        {
+          if (TEST_OPT_DEBUG) PrintS("+");
+          /*
+          * the polynomial to reduce with is now;
+          */
+          pi = strat->T[i].p;
+          ei = strat->T[i].ecart;
+        }
+        else if (TEST_OPT_DEBUG) PrintS("-");
+      }
+
+      /*
+      * end of search: have to reduce with pi
+      */
+      if (ei > (*h).ecart)
+      {
+        /*
+        * It is not possible to reduce h with smaller ecart;
+        * if possible h goes to the lazy-set L,i.e
+        * if its position in L would be not the last one
+        */
+        if (strat->Ll >= 0) /* L is not empty */
+        {
+          at = strat->posInL(strat->L,strat->Ll,h,strat);
+          if(at <= strat->Ll)
+          /*- h will not become the next element to reduce -*/
+          {
+            enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+            if (TEST_OPT_DEBUG) Print(" ecart too big: -> L%d\n",at);
+            (*h).p = NULL;
+            return 0;
+          }
+        }
+      }
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("\nwith ");
+        wrp(pi);
+      }
+      if (strat->fromT)
+      {
+        strat->fromT=FALSE;
+        (*h).p = nc_spGSpolyRedNew(pi,(*h).p,strat->kNoether,currRing);
+      }
+      else
+        (*h).p = nc_spGSpolyRed(pi,(*h).p,strat->kNoether,currRing);
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS(" to ");
+        wrp((*h).p);
+        PrintLn();
+      }
+      if ((*h).p == NULL)
+      {
+        if (h->lcm!=NULL) pLmFree((*h).lcm);
+        (*h).lcm=NULL;
+        return 0;
+      }
+      /* compute the ecart */
+      if (ei <= (*h).ecart)
+        (*h).ecart = d-pFDeg((*h).p);
+      else
+        (*h).ecart = d-pFDeg((*h).p)+ei-(*h).ecart;
+//      if (strat->syzComp)
+//      {
+//        if ((strat->syzComp>0) && (pMinComp((*h).p) > strat->syzComp))
+//        {
+//          if (TEST_OPT_DEBUG)
+//            PrintS("  >syzComp\n");
+//          if (TEST_OPT_INTSTRATEGY) pContent(h->p);
+//          at=strat->posInT(strat->T,strat->tl,(*h));
+//          enterTBba((*h),at,strat);
+//          return;
+//        }
+//      }
+      /*
+      * try to reduce the s-polynomial h
+      *test first whether h should go to the lazyset L
+      *-if the degree jumps
+      *-if the number of pre-defined reductions jumps
+      */
+      pass++;
+      d = pFDeg((*h).p)+(*h).ecart;
+      if ((strat->Ll >= 0) && ((d > reddeg) || (pass > strat->LazyPass)))
+      {
+        at = strat->posInL(strat->L,strat->Ll,h,strat);
+        if (at <= strat->Ll)
+        {
+          /*test if h is already standardbasis element*/
+          i=strat->sl+1;
+          do
+          {
+            i--;
+            if (i<0)
+            {
+              enterT((*h),strat);
+              return 0;
+            }
+          } while (!pDivisibleBy(strat->S[i],(*h).p));
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+          if (TEST_OPT_DEBUG)
+            Print(" degree jumped: -> L%d\n",at);
+          (*h).p = NULL;
+          return 0;
+        }
+      }
+      else if (TEST_OPT_PROT && (strat->Ll < 0) && (d > reddeg))
+      {
+        reddeg = d;
+        Print(".%d",d); mflush();
+      }
+      j = 0;
+    }
+    else
+    {
+      if (TEST_OPT_DEBUG) PrintS("-");
+      if (j >= strat->tl)
+      {
+        if (TEST_OPT_DEBUG) PrintLn();
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          //pContent(h->p);
+          pCleardenom(h->p);// also does a pContent
+        }
+        enterT((*h),strat);
+        return 0;
+      }
+      j++;
+    }
+  }
+}
+
+/*2
+*  reduction procedure for tests only
+*  reduces with elements from T and chooses the best possible
+*/
+static int redBest (LObject*  h,kStrategy strat)
+{
+  if (strat->tl<0)
+  {
+    enterT((*h),strat);
+    return 0;
+  }
+
+  int j,jbest,at,reddeg,d,pass;
+  poly     p,ph;
+  pass = j = 0;
+
+  if (strat->honey)
+    reddeg = pFDeg((*h).p)+(*h).ecart;
+  else
+    reddeg = pFDeg((*h).p);
+  loop
+  {
+    if (pDivisibleBy(strat->T[j].p,(*h).p))
+    {
+      /* compute the s-polynomial */
+      if (!TEST_OPT_INTSTRATEGY) pNorm((*h).p);
+#ifdef SDRING
+      // spSpolyShortBba will not work in the SRING case
+      if (pSDRING)
+      {
+        p=spSpolyCreate(strat->T[j].p,(*h).p,strat->kNoether);
+        if (p!=NULL) pDelete(&pNext(p));
+      }
+      else
+#endif
+      p = nc_spShort(strat->T[j].p,(*h).p);
+      /* computes only the first monomial of the spoly  */
+      if (p)
+      {
+        jbest = j;
+        /* looking for the best possible reduction */
+        if ((strat->syzComp==0) || (pMinComp(p) <= strat->syzComp))
+        {
+          loop
+          {
+            j++;
+            if (j > strat->tl)
+              break;
+            if (pDivisibleBy(strat->T[j].p,(*h).p))
+            {
+#ifdef SDRING
+              // spSpolyShortBba will not work in the SRING case
+              if (pSDRING)
+              {
+                ph=spSpolyCreate(strat->T[j].p,(*h).p,strat->kNoether);
+                if (ph!=NULL) pDelete(&pNext(ph));
+              }
+              else
+#endif
+              ph = nc_spShort(strat->T[j].p,(*h).p);
+              if (ph==NULL)
+              {
+                pLmFree(p);
+                pDelete(&((*h).p));
+                if (h->lcm!=NULL)
+                {
+                  pLmFree((*h).lcm);
+                  (*h).lcm=NULL;
+                }
+                return 0;
+              }
+              else if (pLmCmp(ph,p) == -1)
+              {
+                pLmFree(p);
+                p = ph;
+                jbest = j;
+              }
+              else
+              {
+                pLmFree(ph);
+              }
+            }
+          }
+        }
+        pLmFree(p);
+        (*h).p = nc_spGSpolyRed(strat->T[jbest].p,(*h).p,strat->kNoether,currRing);
+      }
+      else
+      {
+        if (h->lcm!=NULL)
+        {
+          pLmFree((*h).lcm);
+          (*h).lcm=NULL;
+        }
+        (*h).p = NULL;
+        return 0;
+      }
+      if (strat->honey && pLexOrder)
+        strat->initEcart(h);
+      /* h.length:=l; */
+      /* try to reduce the s-polynomial */
+//      if (strat->syzComp)
+//      {
+//        if ((strat->syzComp>0) && (pMinComp((*h).p) > strat->syzComp))
+//        {
+//          if (TEST_OPT_DEBUG)
+//            PrintS(" >syzComp\n");
+//          if (TEST_OPT_INTSTRATEGY) pContent(h->p);
+//          at=strat->posInT(strat->T,strat->tl,(*h));
+//          enterTBba((*h),at,strat);
+//          return;
+//        }
+//      }
+      if (strat->honey || pLexOrder)
+      {
+        pass++;
+        d = pFDeg((*h).p);
+        if (strat->honey)
+          d += (*h).ecart;
+        if ((strat->Ll >= 0) && ((pass > strat->LazyPass) || (d > reddeg)))
+        {
+          at = strat->posInL(strat->L,strat->Ll,h,strat);
+          if (at <= strat->Ll)
+          {
+            enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+            (*h).p = NULL;
+            return 0;
+          }
+        }
+        else if (TEST_OPT_PROT && (strat->Ll < 0) && (d != reddeg))
+        {
+          reddeg = d;
+          Print("%d.");
+          mflush();
+        }
+      }
+      j = 0;
+    }
+    else
+    {
+      if (j >= strat->tl)
+      {
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          //pContent(h->p);
+          pCleardenom(h->p);// also does a pContent
+        }
+        enterT((*h),strat);
+        return 0;
+      }
+      j++;
+    }
+  }
+}
+
+static void gr_initBba(ideal F,kStrategy strat)
+{
+  int i;
+  idhdl h;
+ /* setting global variables ------------------- */
+  strat->enterS = enterSBba;
+  if ((BTEST1(20)) && (!strat->honey))
+    strat->red = redBest;
+  else if (strat->honey)
+    strat->red = redHoney;
+  else if (pLexOrder && !strat->homog)
+    strat->red = redLazy;
+  else if (TEST_OPT_INTSTRATEGY && strat->homog)
+    strat->red = redHomog0;
+  else
+    strat->red = redHomog;
+  if (rIsPluralRing(currRing))
+  {
+    strat->red = redGrFirst;
+  }
+  if (pLexOrder && strat->honey)
+    strat->initEcart = initEcartNormal;
+  else
+    strat->initEcart = initEcartBBA;
+  if (strat->honey)
+    strat->initEcartPair = initEcartPairMora;
+  else
+    strat->initEcartPair = initEcartPairBba;
+  strat->kIdeal = NULL;
+  //if (strat->ak==0) strat->kIdeal->rtyp=IDEAL_CMD;
+  //else              strat->kIdeal->rtyp=MODUL_CMD;
+  //strat->kIdeal->data=(void *)strat->Shdl;
+  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
+  {
+    //interred  machen   Aenderung
+    pFDegOld=pFDeg;
+    pLDegOld=pLDeg;
+    h=ggetid("ecart");
+    if ((h!=NULL) && (IDTYP(h)==INTVEC_CMD))
+    {
+      ecartWeights=iv2array(IDINTVEC(h));
+    }
+    else
+    {
+      ecartWeights=(short *)omAlloc((pVariables+1)*sizeof(short));
+      /*uses automatic computation of the ecartWeights to set them*/
+      kEcartWeights(F->m,IDELEMS(F)-1,ecartWeights);
+    }
+    pFDeg=totaldegreeWecart;
+    pLDeg=maxdegreeWecart;
+    for(i=1; i<=pVariables; i++)
+      Print(" %d",ecartWeights[i]);
+    PrintLn();
+    mflush();
+  }
+}
+
+ideal gr_bba (ideal F, ideal Q, kStrategy strat)
+{
+  intvec *w=NULL;
+  intvec *hilb=NULL;
+  int   srmax,lrmax;
+  int   olddeg,reduc;
+  int red_result=1;
+  int hilbeledeg=1,hilbcount=0,minimcnt=0;
+
+  initBuchMoraCrit(strat); /*set Gebauer, honey, sugarCrit*/
+  // initHilbCrit(F,Q,&hilb,strat);
+  /* in plural we don't need Hilb yet */
+  gr_initBba(F,strat);
+  initBuchMoraPos(strat);
+  /*set enterS, spSpolyShort, reduce, red, initEcart, initEcartPair*/
+  /*Shdl=*/initBuchMora(F, Q,strat);
+  strat->posInT=posInT110;
+  srmax = strat->sl;
+  reduc = olddeg = lrmax = 0;
+  /* compute------------------------------------------------------- */
+  while (strat->Ll >= 0)
+  {
+    if (strat->Ll > lrmax) lrmax =strat->Ll;/*stat.*/
+    if (TEST_OPT_DEBUG) messageSets(strat);
+    if (strat->Ll== 0) strat->interpt=TRUE;
+    if (TEST_OPT_DEGBOUND
+    && ((strat->honey && (strat->L[strat->Ll].ecart+pFDeg(strat->L[strat->Ll].p)>Kstd1_deg))
+       || ((!strat->honey) && (pFDeg(strat->L[strat->Ll].p)>Kstd1_deg))))
+    {
+      /*
+      *stops computation if
+      * 24 IN test and the degree +ecart of L[strat->Ll] is bigger then
+      *a predefined number Kstd1_deg
+      */
+      while (strat->Ll >= 0) deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+      break;
+    }
+    /* picks the last element from the lazyset L */
+    strat->P = strat->L[strat->Ll];
+    strat->Ll--;
+    kTest(strat);
+    if (pNext(strat->P.p) == strat->tail)
+    {
+      /* deletes the short spoly and computes */
+      pLmFree(strat->P.p);
+      /* the real one */
+      if ((currRing->nc->type==nc_lie) && pHasNotCF(strat->P.p1,strat->P.p2)) /* prod crit */
+      {
+        strat->cp++;
+        /* prod.crit itself in nc_spGSpolyCreate */
+      }
+      strat->P.p = nc_spGSpolyCreate(strat->P.p1,strat->P.p2,strat->kNoether,currRing);
+    }
+    if (strat->P.p != NULL)
+    {
+      if (TEST_OPT_PROT)
+      message((strat->honey ? strat->P.ecart : 0) + strat->P.pFDeg(),
+              &olddeg,&reduc,strat, red_result);
+      /* reduction of the element chosen from L */
+      strat->red(&strat->P,strat);
+    }
+    if (strat->P.p != NULL)
+    {
+          /* statistic */
+          if (TEST_OPT_PROT)
+          {
+            PrintS("s\n");
+          }
+          /* enter P.p into s and L */
+          {
+            strat->P.sev=0;
+            int pos=posInS(strat,strat->sl,strat->P.p, strat->P.ecart);
+            {
+              if (TEST_OPT_INTSTRATEGY)
+              {
+                if ((strat->syzComp==0)||(!strat->homog))
+                {
+                  strat->P.p = redtailBba(strat->P.p,pos-1,strat);
+                }
+                pCleardenom(strat->P.p);
+              }
+              else
+              {
+                pNorm(strat->P.p);
+                if ((strat->syzComp==0)||(!strat->homog))
+                {
+                  strat->P.p = redtailBba(strat->P.p,pos-1,strat);
+                }
+              }
+              // PLURAL debug
+              /* should be used only internally!!! */
+
+              //pWrite(strat->P.p);
+
+              if (TEST_OPT_DEBUG)
+              {
+                PrintS("new s:");
+                wrp(strat->P.p);
+                PrintLn();
+              }
+              // kTest(strat);
+              //
+              enterpairs(strat->P.p,strat->sl,strat->P.ecart,pos,strat);
+              if (strat->sl==-1) pos=0;
+              else pos=posInS(strat,strat->sl,strat->P.p,strat->P.ecart);
+              strat->enterS(strat->P,pos,strat);
+            }
+            if (hilb!=NULL) khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
+          }
+          if (strat->P.lcm!=NULL) pLmFree(strat->P.lcm);
+      if (strat->sl>srmax) srmax = strat->sl;
+    }
+#ifdef KDEBUG
+    strat->P.lcm=NULL;
+#endif
+    kTest(strat);
+  }
+  if (TEST_OPT_DEBUG) messageSets(strat);
+  /* complete reduction of the standard basis--------- */
+  if (TEST_OPT_REDSB) completeReduce(strat);
+  /* release temp data-------------------------------- */
+  exitBuchMora(strat);
+  if (TEST_OPT_WEIGHTM)
+  {
+    pFDeg=pFDegOld;
+    pLDeg=pLDegOld;
+    if (ecartWeights)
+    {
+      omFreeSize((ADDRESS)ecartWeights,(pVariables+1)*sizeof(short));
+      ecartWeights=NULL;
+    }
+  }
+  if (TEST_OPT_PROT) messageStat(srmax,lrmax,hilbcount,strat);
+  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
+  return (strat->Shdl);
+}
+#endif
Index: kernel/gring.cc
===================================================================
--- kernel/gring.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/gring.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1667 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    gring.cc
+ *  Purpose: noncommutative kernel procedures
+ *  Author:  levandov (Viktor Levandovsky)
+ *  Created: 8/00 - 11/00
+ *  Version: $Id: gring.cc,v 1.1.1.1 2003-10-06 12:15:54 Singular Exp $
+ *******************************************************************/
+#include "mod2.h"
+#ifdef HAVE_PLURAL
+#include "gring.h"
+#include "febase.h"
+#include "ring.h"
+#include "polys.h"
+#include "numbers.h"
+#include "ideals.h"
+#include "matpol.h"
+#include "kbuckets.h"
+#include "kstd1.h"
+#include "sbuckets.h"
+#include "prCopy.h"
+#include "ipid.h"
+#include "p_Mult_q.h"
+
+/* global nc_macros : */
+#define freeT(A,v) omFreeSize((ADDRESS)A,(v+1)*sizeof(int))
+#define freeN(A,k) omFreeSize((ADDRESS)A,k*sizeof(number))
+
+/* poly functions defined in p_Procs : */
+poly nc_pp_Mult_mm(poly p, poly m, const ring r, poly &last)
+{
+  return( nc_p_Mult_mm_Common(p_Copy(p,r), m, 1, r) );
+}
+
+poly nc_p_Mult_mm(poly p, const poly m, const ring r)
+{
+  return( nc_p_Mult_mm_Common(p, m, 1, r) );
+}
+
+poly nc_mm_Mult_p(const poly m, poly p, const ring r)
+{
+  return( nc_p_Mult_mm_Common(p, m, 0, r) );
+}
+
+/* poly nc_p_Mult_mm(poly p, poly m, const ring r); defined below */
+poly nc_p_Minus_mm_Mult_qq(poly p, const poly m, poly q, const ring r)
+{
+  poly mc=p_Neg(p_Copy(m,r),r);
+  poly mmc=nc_mm_Mult_p(mc,p_Copy(q,r),r);
+  p_Delete(&mc,r);
+  p=p_Add_q(p,mmc,r);
+  return(p);
+}
+
+//----------- auxiliary routines--------------------------
+poly _nc_p_Mult_q(poly p, poly q, const int copy, const ring r)
+  /* destroy p,q unless copy=1 */
+{
+  poly res=NULL;
+  poly ghost=NULL;
+  poly qq,pp;
+  if (copy)
+  {
+    qq=p_Copy(q,r);
+    pp=p_Copy(p,r);
+  }
+  else
+  {
+    qq=q;
+    pp=p;
+  }
+  while (qq!=NULL)
+  {
+    res=p_Add_q(res, nc_pp_Mult_mm(pp, p_Head(qq,r), r, ghost), r);
+    qq=p_LmDeleteAndNext(qq,r);
+  }
+  p_Delete(&pp,r);
+  return(res);
+}
+
+poly nc_p_Mult_mm_Common(poly p, const poly m, int side, const ring r)
+/* p is poly, m is mono with coeff, destroys p */
+/* if side==1, computes p_Mult_mm; otherwise, mm_Mult_p */
+{
+  if ((p==NULL) || (m==NULL)) return NULL;
+  /*  if (pNext(p)==NULL) return(nc_mm_Mult_nn(p,pCopy(m),r)); */
+  /* excluded  - the cycle will do it anyway - OK. */
+  if (p_IsConstant(m,r)) return(p_Mult_nn(p,p_GetCoeff(m,r),r));
+
+#ifdef PDEBUG
+  p_Test(p,r);
+  p_Test(m,r);
+#endif
+  poly v=NULL;
+  int rN=r->N;
+  int *P=(int *)omAlloc0((rN+1)*sizeof(int));
+  int *M=(int *)omAlloc0((rN+1)*sizeof(int));
+  /* coefficients: */
+  number cP,cM,cOut;
+  p_GetExpV(m, M, r);
+  cM=p_GetCoeff(m,r);
+  /* components:*/
+  const int expM=p_GetComp(m,r);
+  int expP=0;
+  int expOut=0;
+  /* bucket constraints: */
+  int UseBuckets=1;
+  if (pLength(p)< MIN_LENGTH_BUCKET || TEST_OPT_NOT_BUCKETS) UseBuckets=0;
+  sBucket_pt bu_out;
+  poly out=NULL;
+  if (UseBuckets) bu_out=sBucketCreate(r);
+
+  while (p!=NULL)
+  {
+#ifdef PDEBUG
+    p_Test(p,r);
+#endif
+    expP=p_GetComp(p,r);
+    if (expP==0)
+    {
+      expOut=expM;
+    }
+    else
+    {
+      if (expM==0)
+      {
+        expOut=expP;
+#ifdef PDEBUG
+	if (side) 
+        {
+	  Print("Multiplication in the left module from the right");
+	}
+#endif          
+      }
+      else
+      {
+        /* REPORT_ERROR */
+	const char* s;
+	if (side==1) s="nc_p_Mult_mm";
+	else s="nc_mm_Mult_p";
+	Print("%s: exponent mismatch %d and %d\n",s,expP,expM);
+        expOut=0;
+      }
+    }
+    p_GetExpV(p,P,r);
+    cP=p_GetCoeff(p,r);
+    cOut=n_Mult(cP,cM,r);
+    if (side==1)
+    {
+      v = nc_mm_Mult_nn(P, M, r);      
+    }
+    else
+    {
+      v = nc_mm_Mult_nn(M, P, r);
+    }
+    v = p_Mult_nn(v,cOut,r);
+    p_SetCompP(v,expOut,r);
+    if (UseBuckets) sBucket_Add_p(bu_out,v,pLength(v));
+    else out = p_Add_q(out,v,r);
+    p_DeleteLm(&p,r);
+  }
+  freeT(P,rN);
+  freeT(M,rN);
+  if (UseBuckets)
+  {
+    out = NULL;
+    int len = pLength(out);
+    sBucketDestroyAdd(bu_out, &out, &len);
+  }
+#ifdef PDEBUG
+  p_Test(out,r);
+#endif
+  return(out);
+}
+
+poly nc_mm_Mult_nn(int *F0, int *G0, const ring r)
+/* destroys nothing, no coeffs and exps */
+{
+  poly out=NULL;
+  int i,j;
+  int iF,jG,iG;
+  int rN=r->N;
+  int ExpSize=(((rN+1)*sizeof(int)+sizeof(long)-1)/sizeof(long))*sizeof(long);
+
+  int *F=(int *)omAlloc0((rN+1)*sizeof(int));
+  int *G=(int *)omAlloc0((rN+1)*sizeof(int));
+
+  memcpy(F, F0,(rN+1)*sizeof(int));
+  // pExpVectorCopy(F,F0);
+  memcpy(G, G0,(rN+1)*sizeof(int));
+  //  pExpVectorCopy(G,G0);
+  F[0]=0; /* important for p_MemAdd */
+  G[0]=0;
+
+  iF=rN;
+  while ((F[iF]==0)&&(iF>=1)) iF--; /* last exp_num of F */
+  if (iF==0) /* F0 is zero vector */
+  {
+    out=pOne();
+    p_SetExpV(out,G0,r);
+    p_Setm(out,r);
+    freeT(F,rN);
+    freeT(G,rN);
+    return(out);
+  }
+  jG=1;
+  while ((G[jG]==0)&&(jG<rN)) jG++;  /* first exp_num of G */
+  iG=rN;
+  while ((G[iG]==0)&&(iG>1)) iG--;  /* last exp_num of G */
+
+  out=pOne();
+
+  if (iF<=jG)
+    /* i.e. no mixed exp_num , MERGE case */
+  {
+    p_MemAdd_LengthGeneral(F, G, ExpSize/sizeof(long));
+    p_SetExpV(out,F,r);
+    p_Setm(out,r);
+    //    omFreeSize((ADDRESS)F,ExpSize);
+    freeT(F,rN);
+    freeT(G,rN);
+    return(out);
+  }
+
+  number cff=n_Init(1,r);
+  number tmp_num=NULL;
+  int cpower=0;
+
+  if (r->nc->type==nc_skew)
+  {
+    if (r->nc->IsSkewConstant==1)
+    {
+      int tpower=0;
+      for(j=jG; j<=iG; j++)
+      {
+        if (G[j]!=0)
+        {
+          cpower = 0;
+          for(i=j+1; i<=iF; i++)
+          {
+            cpower = cpower + F[i];
+          }
+          cpower = cpower*G[j];
+          tpower = tpower + cpower;
+        }
+      }
+      cff = n_Copy(p_GetCoeff(MATELEM(r->nc->COM,1,2),r),r);
+      nPower(cff,tpower,&tmp_num);
+      n_Delete(&cff,r);
+      cff = tmp_num;
+    }
+    else /* skew commutative with nonequal coeffs */
+    {
+      number totcff=n_Init(1,r);
+      for(j=jG; j<=iG; j++)
+      {
+        if (G[j]!=0)
+        {
+          cpower = 0;
+          for(i=j+1; i<=iF; i++)
+          {
+            if (F[i]!=0)
+            {
+              cpower = F[i]*G[j];
+              cff = n_Copy(p_GetCoeff(MATELEM(r->nc->COM,j,i),r),r);
+              nPower(cff,cpower,&tmp_num);
+              cff = nMult(totcff,tmp_num);
+	      nDelete(&totcff);
+              nDelete(&tmp_num);
+              totcff = n_Copy(cff,r);
+              n_Delete(&cff,r);
+            }
+          } /* end 2nd for */
+        }
+      }
+      cff=totcff;
+    }
+    p_MemAdd_LengthGeneral(F, G, ExpSize/sizeof(long));
+    p_SetExpV(out,F,r);
+    p_Setm(out,r);
+    p_SetCoeff(out,cff,r);
+    //    p_MemAdd_NegWeightAdjust(p, r); ??? do we need this?
+    freeT(F,rN);
+    freeT(G,rN);
+    return(out);
+  } /* end nc_skew */
+    
+  /* now we have to destroy out! */
+  p_Delete(&out,r);  
+  out = NULL;  
+
+  if (iG==jG)
+    /* g is univariate monomial */
+  {
+    /*    if (ri->nc->type==nc_skew) -- postpone to TU */
+    out = nc_mm_Mult_uu(F,jG,G[jG],r);
+    freeT(F,rN);
+    freeT(G,rN);
+    return(out);
+  }
+
+  number n1=n_Init(1,r);
+  int *Prv=(int *)omAlloc0((rN+1)*sizeof(int));
+  int *Nxt=(int *)omAlloc0((rN+1)*sizeof(int));
+
+  int *log=(int *)omAlloc0((rN+1)*sizeof(int));
+  int cnt=0; int cnf=0;
+
+  /* splitting F wrt jG */
+  for (i=1;i<=jG;i++)
+  {
+    Prv[i]=F[i]; Nxt[i]=0; /* mult at the very end */
+    if (F[i]!=0) cnf++;
+  }
+
+  if (cnf==0) freeT(Prv,rN);
+
+  for (i=jG+1;i<=rN;i++)
+  {
+    Nxt[i]=F[i];
+    /*    if (cnf!=0)  Prv[i]=0; */
+    if (F[i]!=0)
+    {
+      cnt++;
+    }              /* effective part for F */
+  }
+  freeT(F,rN);
+  cnt=0;
+
+  for (i=1;i<=rN;i++)
+  {
+    if (G[i]!=0)
+    {
+     cnt++;
+     log[cnt]=i;
+     }               /* lG for G */
+   }
+
+/* ---------------------- A C T I O N ------------------------ */
+  poly D=NULL;
+  poly Rout=NULL;
+  number *c=(number *)omAlloc0((rN+1)*sizeof(number));
+  c[0]=n_Init(1,r);
+
+  int *Op=Nxt;
+  int *On=G;
+  int *U=(int *)omAlloc0((rN+1)*sizeof(int));
+
+  for (i=jG;i<=rN;i++) U[i]=Nxt[i]+G[i];  /* make leadterm */
+  Nxt=NULL;
+  G=NULL;
+  cnt=1;
+  int t=0;
+  poly w=NULL;
+  poly Pn=pOne();
+  p_SetExpV(Pn,On,r);
+  p_Setm(Pn,r);
+
+  while (On[iG]!=0)
+  {
+     t=log[cnt];
+
+     w=nc_mm_Mult_uu(Op,t,On[t],r);
+     c[cnt]=n_Mult(c[cnt-1],p_GetCoeff(w,r),r);
+     D = pNext(w);  /* getting coef and rest D */
+     p_DeleteLm(&w,r);
+     w=NULL;
+
+     Op[t] += On[t];   /* update exp_vectors */
+     On[t] = 0;
+
+     if (t!=iG)    /* not the last step */
+     {
+       p_SetExpV(Pn,On,r);
+       p_Setm(Pn,r);
+#ifdef PDEBUG
+       p_Test(Pn,r);
+#endif
+
+//       if (pNext(D)==0)
+// is D a monomial? could be postponed higher
+//       {
+//       Rout=nc_mm_Mult_nn(D,Pn,r);
+//       }
+//       else
+//       {
+       Rout=nc_p_Mult_mm(D,Pn,r);
+//       }
+     }
+     else
+     {
+       Rout=D;
+       D=NULL;
+     }
+
+     if (Rout!=NULL)
+     {
+       Rout=p_Mult_nn(Rout,c[cnt-1],r); /* Rest is ready */
+       out=p_Add_q(out,Rout,r);
+       Rout=NULL;
+     }
+     cnt++;
+  }
+  freeT(On,rN);
+  freeT(Op,rN);
+  p_Delete(&Pn,r);
+  omFreeSize((ADDRESS)log,(rN+1)*sizeof(int));
+
+  /* leadterm and Prv-part */
+
+  Rout=pOne();
+  /* U is lead.monomial */
+  U[0]=0;
+  p_SetExpV(Rout,U,r);
+  p_Setm(Rout,r);  /* use again this name Rout */
+#ifdef PDEBUG
+  p_Test(Rout,r);
+#endif
+  p_SetCoeff(Rout,c[cnt-1],r);
+  out=p_Add_q(out,Rout,r);
+  freeT(U,rN);
+  freeN(c,rN+1);
+  if (cnf!=0)  /* Prv is non-zero vector */
+  {
+    Rout=pOne();
+    Prv[0]=0;
+    p_SetExpV(Rout,Prv,r);
+    p_Setm(Rout,r);
+#ifdef PDEBUG
+    p_Test(Rout,r);
+#endif
+    out=nc_mm_Mult_p(Rout,out,r); /* getting the final result */
+    freeT(Prv,rN);
+    p_Delete(&Rout,r);
+  }
+  return (out);
+}
+
+
+poly nc_mm_Mult_uu(int *F,int jG,int bG, const ring r)
+/* f=mono(F),g=(x_iG)^bG */
+{
+  poly out=NULL;
+  int i;
+  number num=NULL;
+
+  int rN=r->N;
+  int iF=r->N;
+  while ((F[iF]==0)&&(iF>0)) iF-- ;   /* last exponent_num of F */
+
+  if (iF==0)  /* F==zero vector in other words */
+  {
+   out=pOne();
+   p_SetExp(out,jG,bG,r);
+   p_Setm(out,r);
+   return(out);
+  }
+
+  int jF=1;
+  while ((F[jF]==0)&&(jF<=rN)) jF++;  /* first exp of F */
+
+  if (iF<=jG)                       /* i.e. no mixed exp_num */
+  {
+    out=pOne();
+    F[jG]=F[jG]+bG;
+    p_SetExpV(out,F,r);
+    p_Setm(out,r);
+    return(out);
+  }
+
+  if (iF==jF)              /* uni times uni */
+  {
+   out=nc_uu_Mult_ww(iF,F[iF],jG,bG,r);
+   return(out);
+  }
+
+  /* Now: F is mono with >=2 exponents, jG<iF */
+  /* check the quasi-commutative case */
+//   matrix LCOM=r->nc->COM;
+//   number rescoef=n_Init(1,r);
+//   number tmpcoef=n_Init(1,r);
+//   int tmpint;
+//   i=iF;
+//   while (i>=jG+1)
+//     /* all the non-zero exponents */
+//   {
+//     if (MATELEM(LCOM,jG,i)!=NULL)
+//     {
+//       tmpcoef=pGetCoeff(MATELEM(LCOM,jG,i));
+//       tmpint=(int)F[i];
+//       nPower(tmpcoef,F[i],&tmpcoef);
+//       rescoef=nMult(rescoef,tmpcoef);
+//       i--;
+//     }
+//     else
+//     {
+//       if (F[i]!=0) break;
+//     }
+//   }
+//   if (iF==i)
+//   /* no action took place*/
+//   {
+
+//   }
+//   else /* power the result up to bG */
+//   {
+//     nPower(rescoef,bG,&rescoef);
+//     /* + cleanup, post-processing */
+//   }
+
+  int *Prv=(int*)omAlloc0((rN+1)*sizeof(int));
+  int *Nxt=(int*)omAlloc0((rN+1)*sizeof(int));
+  int *lF=(int *)omAlloc0((rN+1)*sizeof(int));
+  int cnt=0; int cnf=0;
+  /* splitting F wrt jG */
+  for (i=1;i<=jG;i++) /* mult at the very end */
+  {
+    Prv[i]=F[i]; Nxt[i]=0;
+    if (F[i]!=0) cnf++;
+  }
+  if (cnf==0)  freeT(Prv,rN);
+  for (i=jG+1;i<=rN;i++)
+  {
+    Nxt[i]=F[i];
+    if (cnf!=0) { Prv[i]=0;}
+    if (F[i]!=0)
+    {
+      cnt++;
+      lF[cnt]=i;
+    }                 /* eff_part,lF_for_F */
+  }
+
+  if (cnt==1) /* Nxt consists of 1 nonzero el-t only */
+  {
+    int q=lF[1];
+    poly Rout=pOne();
+    out=nc_uu_Mult_ww(q,Nxt[q],jG,bG,r);
+    freeT(Nxt,rN);
+
+    if (cnf!=0)
+    {
+       Prv[0]=0;
+       p_SetExpV(Rout,Prv,r);
+       p_Setm(Rout,r);
+#ifdef PDEBUG
+       p_Test(Rout,r);
+#endif
+       freeT(Prv,rN);
+       out=nc_mm_Mult_p(Rout,out,r); /* getting the final result */
+    }
+
+    omFreeSize((ADDRESS)lF,(rN+1)*sizeof(int));
+    p_Delete(&Rout,r);
+    return (out);
+  }
+/* -------------------- MAIN ACTION --------------------- */
+
+  poly D=NULL;
+  poly Rout=NULL;
+  number *c=(number *)omAlloc0((cnt+2)*sizeof(number));
+  c[cnt+1]=n_Init(1,r);
+  i=cnt+2;         /* later in freeN */
+  int *Op=Nxt;
+  int *On=(int *)omAlloc0((rN+1)*sizeof(int));
+  int *U=(int *)omAlloc0((rN+1)*sizeof(int));
+
+
+  //  pExpVectorCopy(U,Nxt);
+  memcpy(U, Nxt,(rN+1)*sizeof(int));
+  U[jG] = U[jG] + bG;
+
+  /* Op=Nxt and initial On=(0); */
+  Nxt=NULL;
+
+  poly Pp;
+  poly Pn;
+  int t=0;
+  int first=lF[1];
+  int nlast=lF[cnt];
+  int kk=0;
+  /*  cnt--;   */
+  /* now lF[cnt] should be <=iF-1 */
+
+  while (Op[first]!=0)
+  {
+     t=lF[cnt];   /* cnt as it was computed */
+
+     poly w=nc_uu_Mult_ww(t,Op[t],jG,bG,r);
+     c[cnt]=n_Copy(p_GetCoeff(w,r),r);
+     D = pNext(w);  /* getting coef and rest D */
+     p_DeleteLm(&w,r);
+     w=NULL;
+
+     Op[t]= 0;
+     Pp=pOne();
+     p_SetExpV(Pp,Op,r);
+     p_Setm(Pp,r);
+
+     if (t<nlast)
+     {
+       kk=lF[cnt+1];
+       On[kk]=F[kk];
+
+       Pn=pOne();
+       p_SetExpV(Pn,On,r);
+       p_Setm(Pn,r);
+
+       if (t!=first)   /* typical expr */
+       {
+         w=nc_p_Mult_mm(D,Pn,r);
+         Rout=nc_mm_Mult_p(Pp,w,r);
+         w=NULL;
+       }
+       else                   /* last step */
+       {
+         On[t]=0;
+         p_SetExpV(Pn,On,r);
+         p_Setm(Pn,r);
+         Rout=nc_p_Mult_mm(D,Pn,r);
+       }
+#ifdef PDEBUG
+       p_Test(Pp,r);
+#endif
+       p_Delete(&Pn,r);
+     }
+     else                     /* first step */
+     {
+       Rout=nc_mm_Mult_p(Pp,D,r);
+     }
+#ifdef PDEBUG
+     p_Test(Pp,r);
+#endif
+     p_Delete(&Pp,r);
+     num=n_Mult(c[cnt+1],c[cnt],r);
+     n_Delete(&c[cnt],r);
+     c[cnt]=num;
+     Rout=p_Mult_nn(Rout,c[cnt+1],r); /* Rest is ready */
+     out=p_Add_q(out,Rout,r);
+     Pp=NULL;
+     cnt--;
+  }
+  /* only to feel safe:*/
+  Pn=Pp=NULL;
+  freeT(On,rN);
+  freeT(Op,rN);
+
+/* leadterm and Prv-part with coef 1 */
+/*  U[0]=exp; */
+/*  U[jG]=U[jG]+bG;  */
+/* make leadterm */
+/* ??????????? we have done it already :-0 */
+  Rout=pOne();
+  p_SetExpV(Rout,U,r);
+  p_Setm(Rout,r);  /* use again this name */
+  p_SetCoeff(Rout,c[cnt+1],r);  /* last computed coef */
+  out=p_Add_q(out,Rout,r);
+  Rout=NULL;
+  freeT(U,rN);
+  freeN(c,i);
+  omFreeSize((ADDRESS)lF,(rN+1)*sizeof(int));
+
+  if (cnf!=0)
+  {
+    Rout=pOne();
+    p_SetExpV(Rout,Prv,r);
+    p_Setm(Rout,r);
+    freeT(Prv,rN);
+    out=nc_mm_Mult_p(Rout,out,r); /* getting the final result */
+    p_Delete(&Rout,r);
+  }
+  return (out);
+}
+
+poly nc_uu_Mult_ww_vert (int i, int a, int j, int b, const ring r)
+{
+  int k,m;
+  int rN=r->N;
+  matrix cMT=r->nc->MT[UPMATELEM(j,i,rN)];         /* cMT=current MT */
+
+  poly x=pOne();p_SetExp(x,j,1,r);p_Setm(x,r);
+/* var(j); */
+  poly y=pOne();p_SetExp(y,i,1,r);p_Setm(y,r);
+/*var(i);  for convenience */
+#ifdef PDEBUG
+  p_Test(x,r);
+  p_Test(y,r);
+#endif
+  poly t=NULL;
+/* ------------ Main Cycles ----------------------------*/
+
+  for (k=2;k<=a;k++)
+  {
+     t = nc_p_CopyGet(MATELEM(cMT,k,1),r);
+
+     if (t==NULL)   /* not computed yet */
+     {
+       t = nc_p_CopyGet(MATELEM(cMT,k-1,1),r);
+       //        t=p_Copy(MATELEM(cMT,k-1,1),r);
+       t = nc_mm_Mult_p(y,t,r);
+       MATELEM(cMT,k,1) = nc_p_CopyPut(t,r);
+       //        omCheckAddr(cMT->m);
+       p_Delete(&t,r);
+     }
+     t=NULL;
+  }
+
+  for (m=2;m<=b;m++)
+  {
+    t = nc_p_CopyGet(MATELEM(cMT,a,m),r);
+    //     t=MATELEM(cMT,a,m);
+    if (t==NULL)   //not computed yet
+    {
+      t = nc_p_CopyGet(MATELEM(cMT,a,m-1),r);
+      //      t=p_Copy(MATELEM(cMT,a,m-1),r);
+      t = nc_p_Mult_mm(t,x,r);
+      MATELEM(cMT,a,m) = nc_p_CopyPut(t,r);
+      //      MATELEM(cMT,a,m) = t;
+      //        omCheckAddr(cMT->m);
+      p_Delete(&t,r);
+    }
+    t=NULL;
+  }
+  p_Delete(&x,r);
+  p_Delete(&y,r);
+  //  t=MATELEM(cMT,a,b);
+  t= nc_p_CopyGet(MATELEM(cMT,a,b),r);
+  //  return(p_Copy(t,r));
+  /* since the last computed element was cMT[a,b] */
+  return(t);
+}
+
+poly nc_uu_Mult_ww (int i, int a, int j, int b, const ring r)
+  /* (x_i)^a times (x_j)^b */
+  /* x_i = y,  x_j = x ! */
+{
+  /* Check zero exceptions, (q-)commutativity and is there something to do? */
+  assume(a!=0);
+  assume(b!=0);
+  poly out=pOne();
+  if (i<=j)
+  {
+    p_SetExp(out,i,a,r);
+    p_AddExp(out,j,b,r);
+    p_Setm(out,r);
+    return(out);
+  }/* zero exeptions and usual case */
+  /*  if ((a==0)||(b==0)||(i<=j)) return(out); */
+
+  if (MATELEM(r->nc->COM,j,i)!=NULL)
+    /* commutative or quasicommutative case */
+  {
+    p_SetExp(out,i,a,r);
+    p_AddExp(out,j,b,r);
+    p_Setm(out,r);
+    if (r->cf->nIsOne(p_GetCoeff(MATELEM(r->nc->COM,j,i),r))) /* commutative case */
+    {
+      return(out);
+    }
+    else
+    {
+      number tmp_number=p_GetCoeff(MATELEM(r->nc->COM,j,i),r); /* quasicommutative case */
+      nPower(tmp_number,a*b,&tmp_number);
+      p_SetCoeff(out,tmp_number,r);
+      return(out);
+    }
+  }/* end_of commutative or quasicommutative case */
+  p_Delete(&out,r);
+
+  /* we are here if  i>j and variables do not commute or quasicommute */
+  /* in fact, now a>=1 and b>=1; and j<i */
+  /* now check whether the polynomial is already computed */
+  int rN=r->N;
+  int vik = UPMATELEM(j,i,rN);
+  int cMTsize=r->nc->MTsize[vik];
+  int newcMTsize=0;
+  newcMTsize=max(a,b);
+
+  if (newcMTsize<=cMTsize)
+  {
+    out =  nc_p_CopyGet(MATELEM(r->nc->MT[vik],a,b),r);
+    if (out !=NULL) return (out);
+  }
+  int k,m;
+  if (newcMTsize > cMTsize)
+  {
+    int inM=(((newcMTsize+6)/7)*7);
+    assume (inM>=newcMTsize);
+    newcMTsize = inM;
+    //    matrix tmp = (matrix)omAlloc0(inM*inM*sizeof(poly));
+    matrix tmp = mpNew(newcMTsize,newcMTsize);
+
+    for (k=1;k<=cMTsize;k++)
+    {
+      for (m=1;m<=cMTsize;m++)
+      {
+	out = MATELEM(r->nc->MT[UPMATELEM(j,i,rN)],k,m);
+        if ( out != NULL )
+        {
+          MATELEM(tmp,k,m) = out;/*MATELEM(r->nc->MT[UPMATELEM(j,i,rN)],k,m)*/
+          //           omCheckAddr(tmp->m);
+          MATELEM(r->nc->MT[UPMATELEM(j,i,rN)],k,m)=NULL;
+          //           omCheckAddr(r->nc->MT[UPMATELEM(j,i,rN)]->m);
+        }
+      }
+    }
+    id_Delete((ideal *)&(r->nc->MT[UPMATELEM(j,i,rN)]),r);
+    r->nc->MT[UPMATELEM(j,i,rN)] = tmp;
+    tmp=NULL;
+    r->nc->MTsize[UPMATELEM(j,i,rN)] = newcMTsize;
+  }
+  /* The update of multiplication matrix is finished */
+    pDelete(&out);
+    out = nc_uu_Mult_ww_vert(i, a, j, b, r);
+    //    out = nc_uu_Mult_ww_horvert(i, a, j, b, r);
+    return(out);
+}
+
+poly nc_uu_Mult_ww_horvert (int i, int a, int j, int b, const ring r)
+
+{
+  int k,m;
+  int rN=r->N;
+  matrix cMT=r->nc->MT[UPMATELEM(j,i,rN)];         /* cMT=current MT */
+
+  poly x=pOne();p_SetExp(x,j,1,r);p_Setm(x,r);/* var(j); */
+  poly y=pOne();p_SetExp(y,i,1,r);p_Setm(y,r); /*var(i);  for convenience */
+#ifdef PDEBUG
+  p_Test(x,r);
+  p_Test(y,r);
+#endif
+
+  poly t=NULL;
+
+  int toXY;
+  int toYX;
+
+  if (a==1) /* y*x^b, b>=2 */
+  {
+    toXY=b-1;
+    while ( (MATELEM(cMT,1,toXY)==NULL) && (toXY>=2)) toXY--;
+    for (m=toXY+1;m<=b;m++)
+    {
+      t=MATELEM(cMT,1,m);
+      if (t==NULL)   /* remove after debug */
+      {
+        t = p_Copy(MATELEM(cMT,1,m-1),r);
+        t = nc_p_Mult_mm(t,x,r);
+        MATELEM(cMT,1,m) = t;
+        /*        omCheckAddr(cMT->m); */
+      }
+      else
+      {
+        /* Error, should never get there */
+        WarnS("Error: a=1; MATELEM!=0");
+      }
+      t=NULL;
+    }
+    return(p_Copy(MATELEM(cMT,1,b),r));
+  }
+
+  if (b==1) /* y^a*x, a>=2 */
+  {
+    toYX=a-1;
+    while ( (MATELEM(cMT,toYX,1)==NULL) && (toYX>=2)) toYX--;
+    for (m=toYX+1;m<=a;m++)
+    {
+      t=MATELEM(cMT,m,1);
+      if (t==NULL)   /* remove after debug */
+      {
+        t = p_Copy(MATELEM(cMT,m-1,1),r);
+        t = nc_mm_Mult_p(y,t,r);
+        MATELEM(cMT,m,1) = t;
+        /*        omCheckAddr(cMT->m); */
+      }
+      else
+      {
+        /* Error, should never get there */
+        WarnS("Error: b=1, MATELEM!=0");
+      }
+      t=NULL;
+    }
+    return(p_Copy(MATELEM(cMT,a,1),r));
+  }
+
+/* ------------ Main Cycles ----------------------------*/
+  /*            a>1, b>1              */
+
+  int dXY=0; int dYX=0;
+  /* dXY = distance for computing x-mult, then y-mult */
+  /* dYX = distance for computing y-mult, then x-mult */
+  int toX=a-1; int toY=b-1; /* toX = to axe X, toY = to axe Y */
+  toXY=b-1; toYX=a-1;
+  /* if toX==0, toXY = dist. to computed y * x^toXY */
+  /* if toY==0, toYX = dist. to computed y^toYX * x */
+  while ( (MATELEM(cMT,toX,b)==NULL) && (toX>=1)) toX--;
+  if (toX==0) /* the whole column is not computed yet */
+  {
+    while ( (MATELEM(cMT,1,toXY)==NULL) && (toXY>=1)) toXY--;
+    /* toXY >=1 */
+    dXY=b-1-toXY;
+  }
+  dXY=dXY+a-toX; /* the distance to nearest computed y^toX x^b */
+
+  while ( (MATELEM(cMT,a,toY)==NULL) && (toY>=1)) toY--;
+  if (toY==0) /* the whole row is not computed yet */
+  {
+    while ( (MATELEM(cMT,toYX,1)==NULL) && (toYX>=1)) toYX--;
+    /* toYX >=1 */
+    dYX=a-1-toYX;
+  }
+  dYX=dYX+b-toY; /* the distance to nearest computed y^a x^toY */
+
+  if (dYX>=dXY)
+  {
+    /* first x, then y */
+    if (toX==0) /* start with the row*/
+    {
+      for (m=toXY+1;m<=b;m++)
+      {
+        t=MATELEM(cMT,1,m);
+        if (t==NULL)   /* remove after debug */
+        {
+          t = p_Copy(MATELEM(cMT,1,m-1),r);
+          t = nc_p_Mult_mm(t,x,r);
+          MATELEM(cMT,1,m) = t;
+          /*        omCheckAddr(cMT->m); */
+        }
+        else
+        {
+          /* Error, should never get there */
+          WarnS("dYX>=dXY,toXY; MATELEM==0");
+        }
+        t=NULL;
+      }
+      toX=1; /* y*x^b is computed */
+    }
+    /* Now toX>=1 */
+    for (k=toX+1;k<=a;k++)
+    {
+      t=MATELEM(cMT,k,b);
+      if (t==NULL)   /* remove after debug */
+      {
+        t = p_Copy(MATELEM(cMT,k-1,b),r);
+        t = nc_mm_Mult_p(y,t,r);
+        MATELEM(cMT,k,b) = t;
+        /*        omCheckAddr(cMT->m); */
+      }
+      else
+      {
+        /* Error, should never get there */
+        WarnS("dYX>=dXY,toX; MATELEM==0");
+      }
+      t=NULL;
+    }
+  } /* endif (dYX>=dXY) */
+
+
+  if (dYX<dXY)
+  {
+    /* first y, then x */
+    if (toY==0) /* start with the column*/
+    {
+      for (m=toYX+1;m<=a;m++)
+      {
+        t=MATELEM(cMT,m,1);
+        if (t==NULL)   /* remove after debug */
+        {
+          t = p_Copy(MATELEM(cMT,m-1,1),r);
+          t = nc_mm_Mult_p(y,t,r);
+          MATELEM(cMT,m,1) = t;
+          /*        omCheckAddr(cMT->m); */
+        }
+        else
+        {
+          /* Error, should never get there */
+          WarnS("dYX<dXY,toYX; MATELEM==0");
+        }
+        t=NULL;
+      }
+      toY=1; /* y^a*x is computed */
+    }
+    /* Now toY>=1 */
+    for (k=toY+1;k<=b;k++)
+    {
+      t=MATELEM(cMT,a,k);
+      if (t==NULL)   /* remove after debug */
+      {
+        t = p_Copy(MATELEM(cMT,a,k-1),r);
+        t = nc_p_Mult_mm(t,x,r);
+        MATELEM(cMT,a,k) = t;
+        /*        omCheckAddr(cMT->m); */
+      }
+      else
+      {
+        /* Error, should never get there */
+        WarnS("dYX<dXY,toY; MATELEM==0");
+      }
+      t=NULL;
+    }
+  } /* endif (dYX<dXY) */
+
+  p_Delete(&x,r);
+  p_Delete(&y,r);
+  t=p_Copy(MATELEM(cMT,a,b),r);
+  return(t);  /* since the last computed element was cMT[a,b] */
+}
+
+
+/* ----------------------------- Syzygies ---------------------- */
+
+/*2
+* reduction of p2 with p1
+* do not destroy p1, but p2
+* p1 divides p2 -> for use in NF algorithm
+*/
+
+poly nc_spGSpolyRed(poly p1, poly p2,poly spNoether, const ring r)
+{
+  if (p_GetComp(p1,r)!=p_GetComp(p2,r)
+  && (p_GetComp(p1,r)!=0)
+  && (p_GetComp(p2,r)!=0))
+  {
+#ifdef PDEBUG
+    Print("nc_spGSpolyRed: different components");
+#endif
+    return(NULL);
+  }
+  poly m=pOne();
+  p_ExpVectorDiff(m,p2,p1,r);
+  p_Setm(m,r);
+#ifdef PDEBUG
+  p_Test(m,r);
+#endif
+  /* pSetComp(m,r)=0? */
+  poly N=nc_mm_Mult_p(m,p_Head(p1,r),r);
+  number C=n_Copy(p_GetCoeff(N,r),r);
+  number cF=n_Copy(p_GetCoeff(p2,r),r);
+  p2=p_Mult_nn(p2,C,r);
+  poly out = nc_mm_Mult_p(m, p_Copy(pNext(p1),r), r);
+  N=p_Add_q(N,out,r);
+  number MinusOne=n_Init(-1,r);
+  if (!n_Equal(cF,MinusOne,r))
+  {
+    cF=n_Neg(cF,r);
+    N=p_Mult_nn(N,cF,r);
+  }
+  out=p_Add_q(p2,N,r);
+  p_Delete(&m,r);
+  n_Delete(&cF,r);
+  n_Delete(&C,r);
+  n_Delete(&MinusOne,r);
+  return(out);
+}
+
+
+/*3
+* reduction of p2 with p1
+* do not destroy p1 and p2
+* p1 divides p2 -> for use in NF algorithm
+*/
+poly nc_spGSpolyRedNew(poly p1, poly p2,poly spNoether, const ring r)
+{
+  return(nc_spGSpolyRed(p1,p_Copy(p2,r),spNoether,r));
+}
+
+/*4
+* creates the S-polynomial of p1 and p2
+* do not destroy p1 and p2
+*/
+poly nc_spGSpolyCreate(poly p1, poly p2,poly spNoether, const ring r)
+{
+  if ((p_GetComp(p1,r)!=p_GetComp(p2,r))
+  && (p_GetComp(p1,r)!=0)
+  && (p_GetComp(p2,r)!=0))
+  {
+#ifdef PDEBUG
+    Print("nc_spGSpolyCreate : different components!");
+#endif
+    return(NULL);
+  }
+  if ((r->nc->type==nc_lie) && pHasNotCF(p1,p2)) /* prod crit */
+  {
+    return(nc_p_Bracket_qq(pCopy(p2),p1));
+  }
+  poly pL=pOne();
+  poly m1=pOne();
+  poly m2=pOne();
+  pLcm(p1,p2,pL);
+  p_Setm(pL,r);
+#ifdef PDEBUG
+  p_Test(pL,r);
+#endif
+  p_ExpVectorDiff(m1,pL,p1,r);
+  //p_SetComp(m1,0,r);
+  p_Setm(m1,r);
+#ifdef PDEBUG
+  p_Test(m1,r);
+#endif
+  p_ExpVectorDiff(m2,pL,p2,r);
+  //p_SetComp(m2,0,r);
+  p_Setm(m2,r);
+#ifdef PDEBUG
+  p_Test(m2,r);
+#endif
+  p_Delete(&pL,r);
+  /* zero exponents ! */
+  poly M1=nc_mm_Mult_p(m1,p_Head(p1,r),r);
+  number C1=n_Copy(p_GetCoeff(M1,r),r);
+  poly M2=nc_mm_Mult_p(m2,p_Head(p2,r),r);
+  number C2=n_Copy(p_GetCoeff(M2,r),r);
+  M1=p_Mult_nn(M1,C2,r);
+  p_SetCoeff(m1,C2,r);
+  number MinusOne=n_Init(-1,r);
+  if (n_Equal(C1,MinusOne,r))
+  {
+    M2=p_Add_q(M1,M2,r);
+  }
+  else
+  {
+    C1=n_Neg(C1,r);
+    M2=p_Mult_nn(M2,C1,r);
+    M2=p_Add_q(M1,M2,r);
+    p_SetCoeff(m2,C1,r);
+  }
+  /* M1 is killed, M2=res = C2 M1 - C1 M2 */
+  poly tmp=p_Copy(p1,r);
+  tmp=p_LmDeleteAndNext(tmp,r);
+  M1=nc_mm_Mult_p(m1,tmp,r);
+  tmp=p_Copy(p2,r);
+  tmp=p_LmDeleteAndNext(tmp,r);
+  M2=p_Add_q(M2,M1,r);
+  M1=nc_mm_Mult_p(m2,tmp,r);
+  M2=p_Add_q(M2,M1,r);
+  p_Delete(&m1,r);
+  p_Delete(&m2,r);
+  //  n_Delete(&C1,r);
+  //  n_Delete(&C2,r);
+  n_Delete(&MinusOne,r);
+#ifdef PDEBUG
+  p_Test(M2,r);
+#endif
+  return(M2);
+}
+
+/*5
+* reduction of tail(q) with p1
+* lead(p1) divides lead(pNext(q2)) and pNext(q2) is reduced
+* do not destroy p1, but tail(q)
+*/
+void nc_spGSpolyRedTail(poly p1, poly q, poly q2, poly spNoether, const ring r)
+{
+  poly a1=p_Head(p1,r);
+  poly Q=pNext(q2);
+  number cQ=p_GetCoeff(Q,r);
+  poly m=pOne();
+  p_ExpVectorDiff(m,Q,p1,r);
+  //  p_SetComp(m,0,r);
+  p_Setm(m,r);
+#ifdef PDEBUG
+  p_Test(m,r);
+#endif
+  /* pSetComp(m,r)=0? */
+  poly M=nc_mm_Mult_p(m,p_Copy(p1,r),r);
+  number C=p_GetCoeff(M,r);
+  M=p_Add_q(M,nc_mm_Mult_p(m,p_LmDeleteAndNext(p_Copy(p1,r),r),r),r);
+  q=p_Mult_nn(q,C,r);
+  number MinusOne=n_Init(-1,r);
+  if (!n_Equal(cQ,MinusOne,r))
+  {
+    cQ=nNeg(cQ);
+    M=p_Mult_nn(M,cQ,r);
+  }
+  Q=p_Add_q(Q,M,r);
+  pNext(q2)=Q;
+
+  p_Delete(&m,r);
+  n_Delete(&C,r);
+  n_Delete(&cQ,r);
+  n_Delete(&MinusOne,r);
+  /*  return(q); */
+}
+
+/*6
+* creates the commutative lcm(lm(p1),lm(p2))
+* do not destroy p1 and p2
+*/
+poly nc_spShort(poly p1, poly p2, const ring r)
+{
+  if (p_GetComp(p1,r)!=p_GetComp(p2,r))
+  {
+    Print("spShort:exponent mismatch!");
+    return(NULL);
+  }
+  poly m=pOne();
+  pLcm(p1,p2,m);
+  p_Setm(m,r);
+#ifdef PDEBUG
+  p_Test(m,r);
+#endif
+  return(m);
+}
+
+void nc_kBucketPolyRed(kBucket_pt b, poly p, number *c)
+{
+  // b will not by multiplied by any constant in this impl.
+  // ==> *c=1
+  *c=nInit(1);
+  poly m=pOne();
+  pExpVectorDiff(m,kBucketGetLm(b),p);
+  pSetm(m);
+#ifdef PDEBUG
+  pTest(m);
+#endif
+  poly pp=nc_mm_Mult_p(m,pCopy(p),currRing);
+  pDelete(&m);
+  number n=nCopy(pGetCoeff(pp));
+  number MinusOne=nInit(-1);
+  number nn;
+  if (!nEqual(n,MinusOne))
+  {
+    nn=nNeg(nInvers(n));
+  }
+  else nn=nInit(1);
+  nDelete(&n);
+  n=nMult(nn,pGetCoeff(kBucketGetLm(b)));
+  nDelete(&nn);
+  pp=p_Mult_nn(pp,n,currRing);
+  nDelete(&n);
+  nDelete(&MinusOne);
+  int l=pLength(pp);
+  kBucket_Add_q(b,pp,&l);
+}
+
+void nc_PolyPolyRed(poly &b, poly p, number *c)
+  // reduces b with p, do not delete both
+{
+  // b will not by multiplied by any constant in this impl.
+  // ==> *c=1
+  *c=nInit(1);
+  poly m=pOne();
+  pExpVectorDiff(m,pHead(b),p);
+  pSetm(m);
+#ifdef PDEBUG
+  pTest(m);
+#endif
+  poly pp=nc_mm_Mult_p(m,pCopy(p),currRing);
+  pDelete(&m);
+  number n=nCopy(pGetCoeff(pp));
+  number MinusOne=nInit(-1);
+  number nn;
+  if (!nEqual(n,MinusOne))
+  {
+    nn=nNeg(nInvers(n));
+  }
+  else nn=nInit(1);
+  nDelete(&n);
+  n=nMult(nn,pGetCoeff(b));
+  nDelete(&nn);
+  pp=p_Mult_nn(pp,n,currRing);
+  nDelete(&n);
+  nDelete(&MinusOne);
+  b=p_Add_q(b,pp,currRing);
+}
+
+poly nc_p_Bracket_qq(poly p, poly q)
+  /* returns [p,q], destroys p */
+{
+  if (!rIsPluralRing(currRing)) return(NULL);
+  if (pComparePolys(p,q)) return(NULL);
+  /* Components !? */
+  poly Q=NULL;
+  number coef=NULL;
+  poly res=NULL;
+  poly pres=NULL;
+  int UseBuckets=1;
+  if ((pLength(p)< MIN_LENGTH_BUCKET/2) && (pLength(q)< MIN_LENGTH_BUCKET/2) || TEST_OPT_NOT_BUCKETS) UseBuckets=0;
+  sBucket_pt bu_out;
+  if (UseBuckets) bu_out=sBucketCreate(currRing);
+  while (p!=NULL)
+  {
+    Q=q;
+    while(Q!=NULL)
+    {
+      pres=nc_mm_Bracket_nn(p,Q); /* since no coeffs are taken into account there */
+      if (pres!=NULL)
+      {
+        coef=nMult(pGetCoeff(p),pGetCoeff(Q));
+        pres=p_Mult_nn(pres,coef,currRing);
+	if (UseBuckets) sBucket_Add_p(bu_out,pres,pLength(pres));
+	else res=p_Add_q(res,pres,currRing);
+        nDelete(&coef);
+      }
+      pIter(Q);
+    }
+    p=pLmDeleteAndNext(p);
+  }
+  if (UseBuckets)
+  {
+    res = NULL;
+    int len = pLength(res);
+    sBucketDestroyAdd(bu_out, &res, &len);
+  }
+  return(res);
+}
+
+poly nc_mm_Bracket_nn(poly m1, poly m2)
+  /*returns [m1,m2] for two monoms, destroys nothing */
+  /* without coeffs */
+{
+  if (pLmIsConstant(m1) || pLmIsConstant(m1)) return(NULL);
+  if (pLmCmp(m1,m2)==0) return(NULL);
+  int rN=currRing->N;
+  int *M1=(int *)omAlloc0((rN+1)*sizeof(int));
+  int *M2=(int *)omAlloc0((rN+1)*sizeof(int));
+  int *PREFIX=(int *)omAlloc0((rN+1)*sizeof(int));
+  int *SUFFIX=(int *)omAlloc0((rN+1)*sizeof(int));
+  pGetExpV(m1,M1);
+  pGetExpV(m2,M2);
+  poly res=NULL;
+  poly ares=NULL;
+  poly bres=NULL;
+  poly prefix=NULL;
+  poly suffix=NULL;
+  int nMin,nMax;
+  number nTmp=NULL;
+  int i,j,k;
+  for (i=1;i<=rN;i++)
+  {
+    if (M2[i]!=0)
+    {
+      ares=NULL;
+      for (j=1;j<=rN;j++)
+      {
+        if (M1[j]!=0)
+        {
+          bres=NULL;
+          /* compute [ x_j^M1[j],x_i^M2[i] ] */
+          if (i<j) {nMax=j;  nMin=i;} else {nMax=i;  nMin=j;}
+          if ( (i==j) || ((MATELEM(currRing->nc->COM,nMin,nMax)!=NULL) && nIsOne(pGetCoeff(MATELEM(currRing->nc->C,nMin,nMax))) )) /* not (the same exp. or commuting exps)*/
+          { bres=NULL; }
+          else
+          {
+            if (i<j) { bres=nc_uu_Mult_ww(j,M1[j],i,M2[i],currRing); }
+            else bres=nc_uu_Mult_ww(i,M2[i],j,M1[j],currRing);
+            if (nIsOne(pGetCoeff(bres)))
+            {
+              bres=pLmDeleteAndNext(bres);
+            }
+            else
+            {
+              nTmp=nSub(pGetCoeff(bres),nInit(1));
+              pSetCoeff(bres,nTmp); /* only lc ! */
+            }
+#ifdef PDEBUG
+            pTest(bres);
+#endif
+            if (i>j)  bres=p_Neg(bres, currRing);
+          }
+          if (bres!=NULL)
+          {
+            /* now mult (prefix, bres, suffix) */
+            memcpy(SUFFIX, M1,(rN+1)*sizeof(int));
+            memcpy(PREFIX, M1,(rN+1)*sizeof(int));
+            for (k=1;k<=j;k++) SUFFIX[k]=0;
+            for (k=j;k<=rN;k++) PREFIX[k]=0;
+            SUFFIX[0]=0;
+            PREFIX[0]=0;
+            prefix=pOne();
+            suffix=pOne();
+            pSetExpV(prefix,PREFIX);
+            pSetm(prefix);
+            pSetExpV(suffix,SUFFIX);
+            pSetm(suffix);
+            if (!pLmIsConstant(prefix)) bres = nc_mm_Mult_p(prefix, bres,currRing);
+            if (!pLmIsConstant(suffix)) bres = nc_p_Mult_mm(bres, suffix,currRing);
+            ares=p_Add_q(ares, bres,currRing);
+            /* What to give free? */
+            pDelete(&prefix);
+            pDelete(&suffix);
+          }
+        }
+      }
+      if (ares!=NULL)
+      {
+        /* now mult (prefix, bres, suffix) */
+        memcpy(SUFFIX, M2,(rN+1)*sizeof(int));
+        memcpy(PREFIX, M2,(rN+1)*sizeof(int));
+        for (k=1;k<=i;k++) SUFFIX[k]=0;
+        for (k=i;k<=rN;k++) PREFIX[k]=0;
+        SUFFIX[0]=0;
+        PREFIX[0]=0;
+        prefix=pOne();
+        suffix=pOne();
+        pSetExpV(prefix,PREFIX);
+        pSetm(prefix);
+        pSetExpV(suffix,SUFFIX);
+        pSetm(suffix);
+        bres=ares;
+        if (!pLmIsConstant(prefix)) bres = nc_mm_Mult_p(prefix, bres,currRing);
+        if (!pLmIsConstant(suffix)) bres = nc_p_Mult_mm(bres, suffix,currRing);
+        res=p_Add_q(res, bres,currRing);
+        pDelete(&prefix);
+        pDelete(&suffix);
+      }
+    }
+  }
+  freeT(M1, rN);
+  freeT(M2, rN);
+  freeT(PREFIX, rN);
+  freeT(SUFFIX, rN);
+  return(res);
+}
+
+ideal twostd(ideal I)
+{
+  int i;
+  int j;
+  int s;
+  int flag;
+  poly p=NULL;
+  poly q=NULL;
+  ideal J=kStd(I, currQuotient,testHomog,NULL,NULL,0,0,NULL);
+  idSkipZeroes(J);
+  ideal K=NULL;
+  poly varj=NULL;
+  ideal Q=NULL;
+  ideal id_tmp=NULL;
+  int rN=currRing->N;
+  int iSize=0;
+  loop
+  {
+    flag=0;
+    K=NULL;
+    s=idElem(J);
+    for (i=0;i<=s-1;i++)
+    {
+      p=J->m[i];
+      for (j=1;j<=rN;j++)
+      {
+        varj = pOne();
+        pSetExp(varj,j,1);
+        pSetm(varj);
+        q = nc_p_Mult_mm(pCopy(p),varj,currRing);
+        pDelete(&varj);
+        q = nc_spGSpolyRed(p,q,NULL,currRing);
+        q = kNF(J,currQuotient,q,0,0);
+        if (q!=NULL)
+        {
+          if (pIsConstant(q))
+          {
+            Q=idInit(1,1);
+            Q->m[0]=pOne();
+            idDelete(&J);
+            pDelete(&q);
+            if (K!=NULL) idDelete(&K);
+            return(Q);
+          }
+          flag=1;
+          Q=idInit(1,1);
+          Q->m[0]=q;
+          id_tmp=idSimpleAdd(K,Q);
+          idDelete(&K);
+          K=id_tmp;
+          idDelete(&Q);
+        }
+      }
+    }
+    if (flag==0)
+      /* i.e. all elements are two-sided */
+    {
+      idDelete(&K);
+      return(J);
+    }
+    /* now we update GrBasis J with K */
+    iSize=IDELEMS(J);
+    id_tmp=idSimpleAdd(J,K);
+    idDelete(&K);
+    idDelete(&J); 
+    BITSET save_test=test;
+    test|=Sy_bit(OPT_SB_1);
+    J=kStd(id_tmp, currQuotient, testHomog,NULL,NULL,0,iSize);
+    test=save_test;
+    idSkipZeroes(J);
+  }
+}
+
+matrix nc_PrintMat(int a, int b, ring r, int metric)
+  /* returns matrix with the info on noncomm multiplication */
+{
+
+  if ( (a==b) || !rIsPluralRing(r) ) return(NULL);
+  int i;
+  int j;
+  if (a>b) {j=b; i=a;}
+  else {j=a; i=b;}
+  /* i<j */
+  int rN=r->N;
+  int size=r->nc->MTsize[UPMATELEM(i,j,rN)];
+  matrix M = r->nc->MT[UPMATELEM(i,j,rN)];
+  /*  return(M); */
+  int sizeofres;
+  if (metric==0)
+  {
+    sizeofres=sizeof(int);
+  }
+  if (metric==1)
+  {
+    sizeofres=sizeof(number);
+  }
+  matrix res=mpNew(size,size);
+  int s;
+  int t;
+  int length;
+  long totdeg;
+  poly p;
+  for(s=1;s<=size;s++)
+  {
+    for(t=1;t<=size;t++)
+    {
+      p=MATELEM(M,s,t);
+      if (p==NULL)
+      {
+        MATELEM(res,s,t)=0;
+      }
+      else
+      {
+        length = pLength(p);
+        if (metric==0) /* length */
+        {
+          MATELEM(res,s,t)= p_ISet(length,r);
+        }
+        else if (metric==1) /* sum of deg divided by the length */
+        {
+          totdeg=0;
+          while (p!=NULL)
+          {
+            totdeg=totdeg+pDeg(p,r);
+            pIter(p);
+          }
+          number ntd = nInit(totdeg);
+          number nln = nInit(length);
+          number nres=nDiv(ntd,nln);
+          nDelete(&ntd);
+          nDelete(&nln);
+          MATELEM(res,s,t)=p_NSet(nres,r);
+        }
+      }
+    }
+  }
+  return(res);
+}
+
+void ncKill(ring r)
+  /* kills the nc extension of ring r */
+{
+  int i,j;
+  int rN=r->N;
+  for(i=1;i<rN;i++)
+  {
+    for(j=i+1;j<=rN;j++)
+    {
+      id_Delete((ideal *)&(r->nc->MT[UPMATELEM(i,j,rN)]),r->nc->basering);
+    }
+  }
+  omFreeSize((ADDRESS)r->nc->MT,rN*(rN-1)/2*sizeof(matrix));
+  omFreeSize((ADDRESS)r->nc->MTsize,rN*(rN-1)/2*sizeof(int));
+  id_Delete((ideal *)&(r->nc->C),r->nc->basering);
+  id_Delete((ideal *)&(r->nc->D),r->nc->basering);
+  id_Delete((ideal *)&(r->nc->COM),r->nc->basering);
+  omFreeSize((ADDRESS)r->nc,sizeof(nc_struct));
+  r->nc=NULL;
+}
+
+poly nc_p_CopyGet(poly a, ring r)
+/* for use in getting the mult. martix elements*/
+{
+  if (!rIsPluralRing(r)) return(p_Copy(a,r));
+  if (r==r->nc->basering) return(p_Copy(a,r));
+  else
+  {
+    return(prCopyR_NoSort(a,r->nc->basering,r));
+  }
+}
+
+poly nc_p_CopyPut(poly a, ring r)
+/* for use in defining the mult. martix elements*/
+{
+  if (!rIsPluralRing(r)) return(p_Copy(a,r));
+  if (r==r->nc->basering) return(p_Copy(a,r));
+  else
+  {
+    return(prCopyR_NoSort(a,r,r->nc->basering));
+  }
+}
+
+int nc_CheckSubalgebra(poly PolyVar, ring r)
+  /* returns TRUE if product of vars from PolyVar defines */
+  /* an admissible subalgebra of r */
+{
+  int rN=r->N;
+  int *ExpVar=(int*)omAlloc0((rN+1)*sizeof(int));
+  int *ExpTmp=(int*)omAlloc0((rN+1)*sizeof(int));
+  p_GetExpV(PolyVar, ExpVar, r);
+  int i; int j; int k;
+  poly test=NULL;
+  int OK=1;
+  for (i=1;i<rN;i++)
+  {
+    if (ExpVar[i]==0) /* i.e. not in PolyVar */
+    {  
+      for (j=i+1;j<=rN;j++)
+      {
+	if (ExpVar[j]==0)
+	{
+	  test=nc_p_CopyGet(MATELEM(r->nc->D,i,j),r);
+	  while (test!=NULL)
+	  {
+            p_GetExpV(test, ExpTmp, r);
+	    OK=1;
+	    for (k=1;k<=rN;k++)
+            {
+	      if (ExpTmp[k]!=0)
+	      {
+		if (ExpVar[k]!=0) OK=0;
+	      }
+            }
+	    if (!OK) return(FALSE);
+	    pIter(test);
+          }
+	}
+      }
+    }
+  }
+  p_Delete(&test,r);
+  freeT(ExpVar,rN);
+  freeT(ExpTmp,rN);
+  return(TRUE);
+}
+
+// int Commutative_Context(ring r, leftv expression)
+//   /* returns 1 if expression consists */
+//   /*  of commutative elements */
+// {
+//   /* crucial: poly -> ideal, module, matrix  */
+  
+// }
+
+// int Comm_Context_Poly(ring r, poly p)
+// {
+//   poly COMM=r->nc->COMM;
+//   poly pp=pOne();
+//   memset(pp->exp,0,r->ExpL_Size*sizeof(long));
+//   while (p!=NULL)
+//   {
+//     for (i=0;i<=r->ExpL_Size;i++)
+//     {
+//       if ((p->exp[i]) && (pp->exp[i]))  return(FALSE); 
+//       /* nonzero exponent of non-comm variable */
+//     }
+//     pIter(p);
+//   }
+//   return(TRUE);
+// }
+
+#endif
Index: kernel/gring.h
===================================================================
--- kernel/gring.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/gring.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,74 @@
+#ifndef GRING_H
+#define GRING_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: gring.h,v 1.1.1.1 2003-10-06 12:15:54 Singular Exp $ */
+/*
+* ABSTRACT additional defines etc for --with-plural
+*/
+
+#ifdef HAVE_PLURAL
+#include "structs.h"
+
+void ncKill(ring r);
+
+#define UPMATELEM(i,j,nVar) ( (nVar * ((i)-1) - ((i) * ((i)-1))/2 + (j)-1)-(i) )
+// poly functions defined in p_Procs :
+poly nc_pp_Mult_mm(poly p, poly m, const ring r, poly &last);
+poly nc_p_Mult_mm(poly p, poly m, const ring r);
+poly nc_p_Minus_mm_Mult_qq(poly p, const poly m, poly q, const ring r);
+// other routines we need in addition :
+poly nc_p_Mult_mm_Common(poly p, const poly m, int side, const ring r);
+poly nc_mm_Mult_p(const poly m, poly p, const ring r);
+poly nc_mm_Mult_nn (int *F, int *G, const ring r); 
+poly nc_mm_Mult_uu (int *F,int jG,int bG, const ring r);
+
+/* #define nc_uu_Mult_ww nc_uu_Mult_ww_vert */
+poly nc_uu_Mult_ww (int i, int a, int j, int b, const ring r);
+/* poly nc_uu_Mult_ww_vert (int i, int a, int j, int b, const ring r); */
+/* poly nc_uu_Mult_ww_horvert (int i, int a, int j, int b, const ring r); */
+/* poly nc_uu_Mult_ww_hvdiag (int i, int a, int j, int b, const ring r); */
+/* not written yet */
+
+poly _nc_p_Mult_q(poly p, poly q, const int copy, const ring r);
+
+//copy :
+poly nc_p_CopyGet(poly a, ring r);
+poly nc_p_CopyPut(poly a, ring r);
+
+//syzygies :
+poly nc_spGSpolyCreate(poly p1, poly p2, poly spNoether, const ring r);
+poly nc_spGSpolyRed(poly p1, poly p2, poly spNoether, const ring r);
+poly nc_spGSpolyRedNew(poly p1, poly p2, poly spNoether, const ring r);
+void nc_spGSpolyRedTail(poly p1, poly q, poly q2, poly spNoether, const ring r);
+poly nc_spShort(poly p1, poly p2, const ring r=currRing);
+void nc_kBucketPolyRed(kBucket_pt b, poly p);
+
+ideal gr_bba (ideal F, ideal Q,kStrategy strat);
+
+// brackets:
+poly nc_p_Bracket_qq(poly p, poly q);
+poly nc_mm_Bracket_nn(poly m1, poly m2);
+
+//twostd:
+
+ideal twostd(ideal I);
+
+// complete reduction routines
+
+void nc_kBucketPolyRed(kBucket_pt b, poly p, number *c);
+void nc_PolyPolyRed(poly &b, poly p, number *c);
+
+matrix nc_PrintMat(int a, int b, ring r, int metric);
+
+int nc_CheckSubalgebra(poly PolyVar, ring r);
+
+#else
+// dummy definition to make gcc happy
+#define nc_kBucketPolyRed(A,B,C) 0
+#define nc_PolyPolyRed(A,B,C) 0
+
+#endif /* HAVE_PLURAL */
+#endif
+
Index: kernel/hdegree.cc
===================================================================
--- kernel/hdegree.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/hdegree.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1343 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: hdegree.cc,v 1.1.1.1 2003-10-06 12:15:53 Singular Exp $ */
+/*
+*  ABSTRACT -  dimension, multiplicity, HC, kbase
+*/
+
+#include "mod2.h"
+
+
+#include "structs.h"
+#include "febase.h"
+#include "omalloc.h"
+#include "ideals.h"
+#include "polys.h"
+#include "intvec.h"
+#include "numbers.h"
+#include "hutil.h"
+#include "stairc.h"
+
+int  hCo, hMu, hMu2;
+
+/*0 implementation*/
+
+// dimension
+
+void hDimSolve(scmon pure, int Npure, scfmon rad, int Nrad,
+ varset var, int Nvar)
+{
+  int  dn, iv, rad0, b, c, x;
+  scmon pn;
+  scfmon rn;
+  if (Nrad < 2)
+  {
+    dn = Npure + Nrad;
+    if (dn < hCo)
+      hCo = dn;
+    return;
+  }
+  if (Npure+1 >= hCo)
+    return;
+  iv = Nvar;
+  while(pure[var[iv]]) iv--;
+  hStepR(rad, Nrad, var, iv, &rad0);
+  if (rad0!=0)
+  {
+    iv--;
+    if (rad0 < Nrad)
+    {
+      pn = hGetpure(pure);
+      rn = hGetmem(Nrad, rad, radmem[iv]);
+      hDimSolve(pn, Npure + 1, rn, rad0, var, iv);
+      b = rad0;
+      c = Nrad;
+      hElimR(rn, &rad0, b, c, var, iv);
+      hPure(rn, b, &c, var, iv, pn, &x);
+      hLex2R(rn, rad0, b, c, var, iv, hwork);
+      rad0 += (c - b);
+      hDimSolve(pn, Npure + x, rn, rad0, var, iv);
+    }
+    else
+    {
+      hDimSolve(pure, Npure, rad, Nrad, var, iv);
+    }
+  }
+  else
+    hCo = Npure + 1;
+}
+
+int  scDimInt(ideal S, ideal Q)
+{
+  int  mc;
+  hexist = hInit(S, Q, &hNexist);
+  if (!hNexist)
+    return pVariables;
+  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  hvar = (varset)omAlloc((pVariables + 1) * sizeof(int));
+  hpure = (scmon)omAlloc((1 + (pVariables * pVariables)) * sizeof(int));
+  mc = hisModule;
+  if (!mc)
+  {
+    hrad = hexist;
+    hNrad = hNexist;
+  }
+  else
+    hrad = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  radmem = hCreate(pVariables - 1);
+  hCo = pVariables + 1;
+  loop
+  {
+    if (mc)
+      hComp(hexist, hNexist, mc, hrad, &hNrad);
+    if (hNrad)
+    {
+      hNvar = pVariables;
+      hRadical(hrad, &hNrad, hNvar);
+      hSupp(hrad, hNrad, hvar, &hNvar);
+      if (hNvar)
+      {
+        memset(hpure, 0, (pVariables + 1) * sizeof(int));
+        hPure(hrad, 0, &hNrad, hvar, hNvar, hpure, &hNpure);
+        hLexR(hrad, hNrad, hvar, hNvar);
+        hDimSolve(hpure, hNpure, hrad, hNrad, hvar, hNvar);
+      }
+    }
+    else
+    {
+      hCo = 0;
+      break;
+    }
+    mc--;
+    if (mc <= 0)
+      break;
+  }
+  hKill(radmem, pVariables - 1);
+  omFreeSize((ADDRESS)hpure, (1 + (pVariables * pVariables)) * sizeof(int));
+  omFreeSize((ADDRESS)hvar, (pVariables + 1) * sizeof(int));
+  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
+  hDelete(hexist, hNexist);
+  if (hisModule)
+    omFreeSize((ADDRESS)hrad, hNexist * sizeof(scmon));
+  return pVariables - hCo;
+}
+
+// independent set
+static scmon hInd;
+
+static void hIndSolve(scmon pure, int Npure, scfmon rad, int Nrad,
+ varset var, int Nvar)
+{
+  int  dn, iv, rad0, b, c, x;
+  scmon pn;
+  scfmon rn;
+  if (Nrad < 2)
+  {
+    dn = Npure + Nrad;
+    if (dn < hCo)
+    {
+      hCo = dn;
+      for (iv=pVariables; iv; iv--)
+      {
+        if (pure[iv])
+          hInd[iv] = 0;
+        else
+          hInd[iv] = 1;
+      }
+      if (Nrad)
+      {
+        pn = *rad;
+        iv = Nvar;
+        loop
+        {
+          x = var[iv];
+          if (pn[x])
+          {
+            hInd[x] = 0;
+            break;
+          }
+          iv--;
+        }
+      }
+    }
+    return;
+  }
+  if (Npure+1 >= hCo)
+    return;
+  iv = Nvar;
+  while(pure[var[iv]]) iv--;
+  hStepR(rad, Nrad, var, iv, &rad0);
+  if (rad0)
+  {
+    iv--;
+    if (rad0 < Nrad)
+    {
+      pn = hGetpure(pure);
+      rn = hGetmem(Nrad, rad, radmem[iv]);
+      pn[var[iv + 1]] = 1;
+      hIndSolve(pn, Npure + 1, rn, rad0, var, iv);
+      pn[var[iv + 1]] = 0;
+      b = rad0;
+      c = Nrad;
+      hElimR(rn, &rad0, b, c, var, iv);
+      hPure(rn, b, &c, var, iv, pn, &x);
+      hLex2R(rn, rad0, b, c, var, iv, hwork);
+      rad0 += (c - b);
+      hIndSolve(pn, Npure + x, rn, rad0, var, iv);
+    }
+    else
+    {
+      hIndSolve(pure, Npure, rad, Nrad, var, iv);
+    }
+  }
+  else
+  {
+    hCo = Npure + 1;
+    for (x=pVariables; x; x--)
+    {
+      if (pure[x])
+        hInd[x] = 0;
+      else
+        hInd[x] = 1;
+    }
+    hInd[var[iv]] = 0;
+  }
+}
+
+intvec * scIndIntvec(ideal S, ideal Q)
+{
+  intvec *Set=new intvec(pVariables);
+  int  mc,i;
+  hexist = hInit(S, Q, &hNexist);
+  if (hNexist==0)
+  {
+    for(i=0; i<pVariables; i++)
+      (*Set)[i]=1;
+    return Set;
+  }
+  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  hvar = (varset)omAlloc((pVariables + 1) * sizeof(int));
+  hpure = (scmon)omAlloc((1 + (pVariables * pVariables)) * sizeof(int));
+  hInd = (scmon)omAlloc((1 + pVariables) * sizeof(int));
+  mc = hisModule;
+  if (mc==0)
+  {
+    hrad = hexist;
+    hNrad = hNexist;
+  }
+  else
+    hrad = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  radmem = hCreate(pVariables - 1);
+  hCo = pVariables + 1;
+  loop
+  {
+    if (mc!=0)
+      hComp(hexist, hNexist, mc, hrad, &hNrad);
+    if (hNrad!=0)
+    {
+      hNvar = pVariables;
+      hRadical(hrad, &hNrad, hNvar);
+      hSupp(hrad, hNrad, hvar, &hNvar);
+      if (hNvar!=0)
+      {
+        memset(hpure, 0, (pVariables + 1) * sizeof(int));
+        hPure(hrad, 0, &hNrad, hvar, hNvar, hpure, &hNpure);
+        hLexR(hrad, hNrad, hvar, hNvar);
+        hIndSolve(hpure, hNpure, hrad, hNrad, hvar, hNvar);
+      }
+    }
+    else
+    {
+      hCo = 0;
+      break;
+    }
+    mc--;
+    if (mc <= 0)
+      break;
+  }
+  for(i=0; i<pVariables; i++)
+    (*Set)[i] = hInd[i+1];
+  hKill(radmem, pVariables - 1);
+  omFreeSize((ADDRESS)hpure, (1 + (pVariables * pVariables)) * sizeof(int));
+  omFreeSize((ADDRESS)hInd, (1 + pVariables) * sizeof(int));
+  omFreeSize((ADDRESS)hvar, (pVariables + 1) * sizeof(int));
+  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
+  hDelete(hexist, hNexist);
+  if (hisModule)
+    omFreeSize((ADDRESS)hrad, hNexist * sizeof(scmon));
+  return Set;
+}
+
+indset ISet, JSet;
+
+static BOOLEAN hNotZero(scfmon rad, int Nrad, varset var, int Nvar)
+{
+  int  k1, i;
+  k1 = var[Nvar];
+  i = 0;
+  loop
+  {
+    if (rad[i][k1]==0)
+      return FALSE;
+    i++;
+    if (i == Nrad)
+      return TRUE;
+  }
+}
+
+static void hIndep(scmon pure)
+{
+  int iv;
+  intvec *Set;
+
+  Set = ISet->set = new intvec(pVariables);
+  for (iv=pVariables; iv!=0 ; iv--)
+  {
+    if (pure[iv])
+      (*Set)[iv-1] = 0;
+    else
+      (*Set)[iv-1] = 1;
+  }
+  ISet = ISet->nx = (indset)omAlloc0Bin(indlist_bin);
+  hMu++;
+}
+
+void hIndMult(scmon pure, int Npure, scfmon rad, int Nrad,
+ varset var, int Nvar)
+{
+  int  dn, iv, rad0, b, c, x;
+  scmon pn;
+  scfmon rn;
+  if (Nrad < 2)
+  {
+    dn = Npure + Nrad;
+    if (dn == hCo)
+    {
+      if (Nrad==0)
+        hIndep(pure);
+      else
+      {
+        pn = *rad;
+        for (iv = Nvar; iv!=0; iv--)
+        {
+          x = var[iv];
+          if (pn[x])
+          {
+            pure[x] = 1;
+            hIndep(pure);
+            pure[x] = 0;
+          }
+        }
+      }
+    }
+    return;
+  }
+  iv = Nvar;
+  dn = Npure+1;
+  if (dn >= hCo)
+  {
+    if (dn > hCo)
+      return;
+    loop
+    {
+      if(!pure[var[iv]])
+      {
+        if(hNotZero(rad, Nrad, var, iv))
+        {
+          pure[var[iv]] = 1;
+          hIndep(pure);
+          pure[var[iv]] = 0;
+        }
+      }
+      iv--;
+      if (!iv)
+        return;
+    }
+  }
+  while(pure[var[iv]]) iv--;
+  hStepR(rad, Nrad, var, iv, &rad0);
+  iv--;
+  if (rad0 < Nrad)
+  {
+    pn = hGetpure(pure);
+    rn = hGetmem(Nrad, rad, radmem[iv]);
+    pn[var[iv + 1]] = 1;
+    hIndMult(pn, Npure + 1, rn, rad0, var, iv);
+    pn[var[iv + 1]] = 0;
+    b = rad0;
+    c = Nrad;
+    hElimR(rn, &rad0, b, c, var, iv);
+    hPure(rn, b, &c, var, iv, pn, &x);
+    hLex2R(rn, rad0, b, c, var, iv, hwork);
+    rad0 += (c - b);
+    hIndMult(pn, Npure + x, rn, rad0, var, iv);
+  }
+  else
+  {
+    hIndMult(pure, Npure, rad, Nrad, var, iv);
+  }
+}
+
+/*3
+* consider indset x := !pure
+* (for all i) (if(sm(i) > x) return FALSE)
+* else return TRUE
+*/
+static BOOLEAN hCheck1(indset sm, scmon pure)
+{
+  int iv;
+  intvec *Set;
+  while (sm->nx != NULL)
+  {
+    Set = sm->set;
+    iv=pVariables;
+    loop
+    {
+      if (((*Set)[iv-1] == 0) && (pure[iv] == 0))
+        break;
+      iv--;
+      if (iv == 0)
+        return FALSE;
+    }
+    sm = sm->nx;
+  }
+  return TRUE;
+}
+
+/*3
+* consider indset x := !pure
+* (for all i) if(x > sm(i)) delete sm(i))
+* return (place for x)
+*/
+static indset hCheck2(indset sm, scmon pure)
+{
+  int iv;
+  intvec *Set;
+  indset be, a1 = NULL;
+  while (sm->nx != NULL)
+  {
+    Set = sm->set;
+    iv=pVariables;
+    loop
+    {
+      if ((pure[iv] == 1) && ((*Set)[iv-1] == 1))
+        break;
+      iv--;
+      if (iv == 0)
+      {
+        if (a1 == NULL)
+        {
+          a1 = sm;
+        }
+        else
+        {
+          hMu2--;
+          be->nx = sm->nx;
+          delete Set;
+          omFreeBin((ADDRESS)sm, indlist_bin);
+          sm = be;
+        }
+        break;
+      }
+    }
+    be = sm;
+    sm = sm->nx;
+  }
+  if (a1 != NULL)
+  {
+    return a1;
+  }
+  else
+  {
+    hMu2++;
+    sm->set = new intvec(pVariables);
+    sm->nx = (indset)omAlloc0Bin(indlist_bin);
+    return sm;
+  }
+}
+
+/*2
+*  definition x >= y
+*      x(i) == 0 => y(i) == 0
+*      > ex. j with x(j) == 1 and y(j) == 0
+*/
+static void hCheckIndep(scmon pure)
+{
+  intvec *Set;
+  indset res;
+  int iv;
+  if (hCheck1(ISet, pure))
+  {
+    if (hCheck1(JSet, pure))
+    {
+      res = hCheck2(JSet,pure);
+      if (res == NULL)
+        return;
+      Set = res->set;
+      for (iv=pVariables; iv; iv--)
+      {
+        if (pure[iv])
+          (*Set)[iv-1] = 0;
+        else
+          (*Set)[iv-1] = 1;
+      }
+    }
+  }
+}
+
+void hIndAllMult(scmon pure, int Npure, scfmon rad, int Nrad,
+ varset var, int Nvar)
+{
+  int  dn, iv, rad0, b, c, x;
+  scmon pn;
+  scfmon rn;
+  if (Nrad < 2)
+  {
+    dn = Npure + Nrad;
+    if (dn > hCo)
+    {
+      if (!Nrad)
+        hCheckIndep(pure);
+      else
+      {
+        pn = *rad;
+        for (iv = Nvar; iv; iv--)
+        {
+          x = var[iv];
+          if (pn[x])
+          {
+            pure[x] = 1;
+            hCheckIndep(pure);
+            pure[x] = 0;
+          }
+        }
+      }
+    }
+    return;
+  }
+  iv = Nvar;
+  while(pure[var[iv]]) iv--;
+  hStepR(rad, Nrad, var, iv, &rad0);
+  iv--;
+  if (rad0 < Nrad)
+  {
+    pn = hGetpure(pure);
+    rn = hGetmem(Nrad, rad, radmem[iv]);
+    pn[var[iv + 1]] = 1;
+    hIndAllMult(pn, Npure + 1, rn, rad0, var, iv);
+    pn[var[iv + 1]] = 0;
+    b = rad0;
+    c = Nrad;
+    hElimR(rn, &rad0, b, c, var, iv);
+    hPure(rn, b, &c, var, iv, pn, &x);
+    hLex2R(rn, rad0, b, c, var, iv, hwork);
+    rad0 += (c - b);
+    hIndAllMult(pn, Npure + x, rn, rad0, var, iv);
+  }
+  else
+  {
+    hIndAllMult(pure, Npure, rad, Nrad, var, iv);
+  }
+}
+
+// multiplicity
+
+static int hZeroMult(scmon pure, scfmon stc, int Nstc, varset var, int Nvar)
+{
+  int  iv = Nvar -1, sum, a, a0, a1, b, i;
+  int  x, x0;
+  scmon pn;
+  scfmon sn;
+  if (!iv)
+    return pure[var[1]];
+  else if (!Nstc)
+  {
+    sum = 1;
+    for (i = Nvar; i; i--)
+      sum *= pure[var[i]];
+    return sum;
+  }
+  x = a = 0;
+  pn = hGetpure(pure);
+  sn = hGetmem(Nstc, stc, stcmem[iv]);
+  hStepS(sn, Nstc, var, Nvar, &a, &x);
+  if (a == Nstc)
+    return pure[var[Nvar]] * hZeroMult(pn, sn, a, var, iv);
+  else
+    sum = x * hZeroMult(pn, sn, a, var, iv);
+  b = a;
+  loop
+  {
+    a0 = a;
+    x0 = x;
+    hStepS(sn, Nstc, var, Nvar, &a, &x);
+    hElimS(sn, &b, a0, a, var, iv);
+    a1 = a;
+    hPure(sn, a0, &a1, var, iv, pn, &i);
+    hLex2S(sn, b, a0, a1, var, iv, hwork);
+    b += (a1 - a0);
+    if (a < Nstc)
+    {
+      sum += (x - x0) * hZeroMult(pn, sn, b, var, iv);
+    }
+    else
+    {
+      sum += (pure[var[Nvar]] - x0) * hZeroMult(pn, sn, b, var, iv);
+      return sum;
+    }
+  }
+}
+
+static void hProject(scmon pure, varset sel)
+{
+  int  i, i0, k;
+  i0 = 0;
+  for (i = 1; i <= pVariables; i++)
+  {
+    if (pure[i])
+    {
+      i0++;
+      sel[i0] = i;
+    }
+  }
+  i = hNstc;
+  memcpy(hwork, hstc, i * sizeof(scmon));
+  hStaircase(hwork, &i, sel, i0);
+  if ((i0 > 2) && (i > 10))
+    hOrdSupp(hwork, i, sel, i0);
+  memset(hpur0, 0, (pVariables + 1) * sizeof(int));
+  hPure(hwork, 0, &i, sel, i0, hpur0, &k);
+  hLexS(hwork, i, sel, i0);
+  hMu += hZeroMult(hpur0, hwork, i, sel, i0);
+}
+
+static void hDimMult(scmon pure, int Npure, scfmon rad, int Nrad,
+ varset var, int Nvar)
+{
+  int  dn, iv, rad0, b, c, x;
+  scmon pn;
+  scfmon rn;
+  if (Nrad < 2)
+  {
+    dn = Npure + Nrad;
+    if (dn == hCo)
+    {
+      if (!Nrad)
+        hProject(pure, hsel);
+      else
+      {
+        pn = *rad;
+        for (iv = Nvar; iv; iv--)
+        {
+          x = var[iv];
+          if (pn[x])
+          {
+            pure[x] = 1;
+            hProject(pure, hsel);
+            pure[x] = 0;
+          }
+        }
+      }
+    }
+    return;
+  }
+  iv = Nvar;
+  dn = Npure+1;
+  if (dn >= hCo)
+  {
+    if (dn > hCo)
+      return;
+    loop
+    {
+      if(!pure[var[iv]])
+      {
+        if(hNotZero(rad, Nrad, var, iv))
+        {
+          pure[var[iv]] = 1;
+          hProject(pure, hsel);
+          pure[var[iv]] = 0;
+        }
+      }
+      iv--;
+      if (!iv)
+        return;
+    }
+  }
+  while(pure[var[iv]]) iv--;
+  hStepR(rad, Nrad, var, iv, &rad0);
+  iv--;
+  if (rad0 < Nrad)
+  {
+    pn = hGetpure(pure);
+    rn = hGetmem(Nrad, rad, radmem[iv]);
+    pn[var[iv + 1]] = 1;
+    hDimMult(pn, Npure + 1, rn, rad0, var, iv);
+    pn[var[iv + 1]] = 0;
+    b = rad0;
+    c = Nrad;
+    hElimR(rn, &rad0, b, c, var, iv);
+    hPure(rn, b, &c, var, iv, pn, &x);
+    hLex2R(rn, rad0, b, c, var, iv, hwork);
+    rad0 += (c - b);
+    hDimMult(pn, Npure + x, rn, rad0, var, iv);
+  }
+  else
+  {
+    hDimMult(pure, Npure, rad, Nrad, var, iv);
+  }
+}
+
+static void hDegree(ideal S, ideal Q)
+{
+  int  di;
+  int  mc;
+  hexist = hInit(S, Q, &hNexist);
+  if (!hNexist)
+  {
+    hCo = 0;
+    hMu = 1;
+    return;
+  }
+  hWeight();
+  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  hvar = (varset)omAlloc((pVariables + 1) * sizeof(int));
+  hsel = (varset)omAlloc((pVariables + 1) * sizeof(int));
+  hpure = (scmon)omAlloc((1 + (pVariables * pVariables)) * sizeof(int));
+  hpur0 = (scmon)omAlloc((1 + (pVariables * pVariables)) * sizeof(int));
+  mc = hisModule;
+  hrad = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  if (!mc)
+  {
+    memcpy(hrad, hexist, hNexist * sizeof(scmon));
+    hstc = hexist;
+    hNrad = hNstc = hNexist;
+  }
+  else
+    hstc = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  radmem = hCreate(pVariables - 1);
+  stcmem = hCreate(pVariables - 1);
+  hCo = pVariables + 1;
+  di = hCo + 1;
+  loop
+  {
+    if (mc)
+    {
+      hComp(hexist, hNexist, mc, hrad, &hNrad);
+      hNstc = hNrad;
+      memcpy(hstc, hrad, hNrad * sizeof(scmon));
+    }
+    if (hNrad)
+    {
+      hNvar = pVariables;
+      hRadical(hrad, &hNrad, hNvar);
+      hSupp(hrad, hNrad, hvar, &hNvar);
+      if (hNvar)
+      {
+        hCo = hNvar;
+        memset(hpure, 0, (pVariables + 1) * sizeof(int));
+        hPure(hrad, 0, &hNrad, hvar, hNvar, hpure, &hNpure);
+        hLexR(hrad, hNrad, hvar, hNvar);
+        hDimSolve(hpure, hNpure, hrad, hNrad, hvar, hNvar);
+      }
+    }
+    else
+    {
+      hNvar = 1;
+      hCo = 0;
+    }
+    if (hCo < di)
+    {
+      di = hCo;
+      hMu = 0;
+    }
+    if (hNvar && (hCo == di))
+    {
+      if (di && (di < pVariables))
+        hDimMult(hpure, hNpure, hrad, hNrad, hvar, hNvar);
+      else if (!di)
+        hMu++;
+      else
+      {
+        hStaircase(hstc, &hNstc, hvar, hNvar);
+        if ((hNvar > 2) && (hNstc > 10))
+          hOrdSupp(hstc, hNstc, hvar, hNvar);
+        memset(hpur0, 0, (pVariables + 1) * sizeof(int));
+        hPure(hstc, 0, &hNstc, hvar, hNvar, hpur0, &hNpure);
+        hLexS(hstc, hNstc, hvar, hNvar);
+        hMu += hZeroMult(hpur0, hstc, hNstc, hvar, hNvar);
+      }
+    }
+    mc--;
+    if (mc <= 0)
+      break;
+  }
+  hCo = di;
+  hKill(stcmem, pVariables - 1);
+  hKill(radmem, pVariables - 1);
+  omFreeSize((ADDRESS)hpur0, (1 + (pVariables * pVariables)) * sizeof(int));
+  omFreeSize((ADDRESS)hpure, (1 + (pVariables * pVariables)) * sizeof(int));
+  omFreeSize((ADDRESS)hsel, (pVariables + 1) * sizeof(int));
+  omFreeSize((ADDRESS)hvar, (pVariables + 1) * sizeof(int));
+  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
+  omFreeSize((ADDRESS)hrad, hNexist * sizeof(scmon));
+  hDelete(hexist, hNexist);
+  if (hisModule)
+    omFreeSize((ADDRESS)hstc, hNexist * sizeof(scmon));
+}
+
+int  scMultInt(ideal S, ideal Q)
+{
+  hDegree(S, Q);
+  return hMu;
+}
+
+void scPrintDegree(int co, int mu)
+{
+  int di = pVariables-co;
+  if (pOrdSgn == 1)
+  {
+    if (di!=0)
+      Print("// dimension (proj.)  = %d\n// degree      = %d\n", di-1, mu);
+    else
+      Print("// dimension (affine)  = 0\n// degree      = %d\n",       mu);
+  }
+  else
+    Print("// dimension (local)   = %d\n// multiplicity = %d\n", di, mu);
+}
+
+int scDegree(ideal S, ideal Q)
+{
+  hDegree(S, Q);
+  int di = pVariables-hCo;
+  if (di!=0) return hMu;
+  else /*variety is empty or not projective*/ return 0;
+}
+
+static void hDegree0(ideal S, ideal Q)
+{
+  int  mc;
+  hexist = hInit(S, Q, &hNexist);
+  if (!hNexist)
+  {
+    hMu = -1;
+    return;
+  }
+  else
+    hMu = 0;
+  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  hvar = (varset)omAlloc((pVariables + 1) * sizeof(int));
+  hpur0 = (scmon)omAlloc((1 + (pVariables * pVariables)) * sizeof(int));
+  mc = hisModule;
+  if (!mc)
+  {
+    hstc = hexist;
+    hNstc = hNexist;
+  }
+  else
+    hstc = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  stcmem = hCreate(pVariables - 1);
+  loop
+  {
+    if (mc)
+    {
+      hComp(hexist, hNexist, mc, hstc, &hNstc);
+      if (!hNstc)
+      {
+        hMu = -1;
+        break;
+      }
+    }
+    hNvar = pVariables;
+    for (int i = hNvar; i; i--)
+      hvar[i] = i;
+    hStaircase(hstc, &hNstc, hvar, hNvar);
+    hSupp(hstc, hNstc, hvar, &hNvar);
+    if ((hNvar == pVariables) && (hNstc >= pVariables))
+    {
+      if ((hNvar > 2) && (hNstc > 10))
+        hOrdSupp(hstc, hNstc, hvar, hNvar);
+      memset(hpur0, 0, (pVariables + 1) * sizeof(int));
+      hPure(hstc, 0, &hNstc, hvar, hNvar, hpur0, &hNpure);
+      if (hNpure == hNvar)
+      {
+        hLexS(hstc, hNstc, hvar, hNvar);
+        hMu += hZeroMult(hpur0, hstc, hNstc, hvar, hNvar);
+      }
+      else
+        hMu = -1;
+    }
+    else if (hNvar)
+      hMu = -1;
+    mc--;
+    if (mc <= 0 || hMu < 0)
+      break;
+  }
+  hKill(stcmem, pVariables - 1);
+  omFreeSize((ADDRESS)hpur0, (1 + (pVariables * pVariables)) * sizeof(int));
+  omFreeSize((ADDRESS)hvar, (pVariables + 1) * sizeof(int));
+  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
+  hDelete(hexist, hNexist);
+  if (hisModule)
+    omFreeSize((ADDRESS)hstc, hNexist * sizeof(scmon));
+}
+
+int  scMult0Int(ideal S, ideal Q)
+{
+  hDegree0(S, Q);
+  return hMu;
+}
+
+
+// HC
+
+static poly pWork;
+
+static void hHedge(poly hEdge)
+{
+  pSetm(pWork);
+  if (pLmCmp(pWork, hEdge) == pOrdSgn)
+  {
+    for (int i = hNvar; i>0; i--)
+      pSetExp(hEdge,i, pGetExp(pWork,i));
+    pSetm(hEdge);
+  }
+}
+
+
+static void hHedgeStep(scmon pure, scfmon stc,
+                       int Nstc, varset var, int Nvar,poly hEdge)
+{
+  int  iv = Nvar -1, k = var[Nvar], a, a0, a1, b, i;
+  int  x, x0;
+  scmon pn;
+  scfmon sn;
+  if (iv==0)
+  {
+    pSetExp(pWork, k, pure[k]);
+    hHedge(hEdge);
+    return;
+  }
+  else if (Nstc==0)
+  {
+    for (i = Nvar; i>0; i--)
+      pSetExp(pWork, var[i], pure[var[i]]);
+    hHedge(hEdge);
+    return;
+  }
+  x = a = 0;
+  pn = hGetpure(pure);
+  sn = hGetmem(Nstc, stc, stcmem[iv]);
+  hStepS(sn, Nstc, var, Nvar, &a, &x);
+  if (a == Nstc)
+  {
+    pSetExp(pWork, k, pure[k]);
+    hHedgeStep(pn, sn, a, var, iv,hEdge);
+    return;
+  }
+  else
+  {
+    pSetExp(pWork, k, x);
+    hHedgeStep(pn, sn, a, var, iv,hEdge);
+  }
+  b = a;
+  loop
+  {
+    a0 = a;
+    x0 = x;
+    hStepS(sn, Nstc, var, Nvar, &a, &x);
+    hElimS(sn, &b, a0, a, var, iv);
+    a1 = a;
+    hPure(sn, a0, &a1, var, iv, pn, &i);
+    hLex2S(sn, b, a0, a1, var, iv, hwork);
+    b += (a1 - a0);
+    if (a < Nstc)
+    {
+      pSetExp(pWork, k, x);
+      hHedgeStep(pn, sn, b, var, iv,hEdge);
+    }
+    else
+    {
+      pSetExp(pWork, k, pure[k]);
+      hHedgeStep(pn, sn, b, var, iv,hEdge);
+      return;
+    }
+  }
+}
+
+void scComputeHC(ideal S, ideal Q, int ak, poly &hEdge, ring tailRing)
+{
+  int  i;
+  int  k = ak;
+  hNvar = pVariables;
+  hexist = hInit(S, Q, &hNexist, tailRing);
+  if (k!=0)
+    hComp(hexist, hNexist, k, hexist, &hNstc);
+  else
+    hNstc = hNexist;
+  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  hvar = (varset)omAlloc((hNvar + 1) * sizeof(int));
+  hpure = (scmon)omAlloc((1 + (hNvar * hNvar)) * sizeof(int));
+  stcmem = hCreate(hNvar - 1);
+  for (i = hNvar; i>0; i--)
+    hvar[i] = i;
+  hStaircase(hexist, &hNstc, hvar, hNvar);
+  if ((hNvar > 2) && (hNstc > 10))
+    hOrdSupp(hexist, hNstc, hvar, hNvar);
+  memset(hpure, 0, (hNvar + 1) * sizeof(int));
+  hPure(hexist, 0, &hNstc, hvar, hNvar, hpure, &hNpure);
+  hLexS(hexist, hNstc, hvar, hNvar);
+  if (hEdge!=NULL)
+    pLmFree(hEdge);
+  hEdge = pInit();
+  pWork = pInit();
+  hHedgeStep(hpure, hexist, hNstc, hvar, hNvar,hEdge);
+  pSetComp(hEdge,ak);
+  hKill(stcmem, hNvar - 1);
+  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
+  omFreeSize((ADDRESS)hvar, (hNvar + 1) * sizeof(int));
+  omFreeSize((ADDRESS)hpure, (1 + (hNvar * hNvar)) * sizeof(int));
+  hDelete(hexist, hNexist);
+  pLmFree(pWork);
+}
+
+
+//  kbase
+
+static poly last;
+static scmon act;
+
+static void scElKbase()
+{
+  poly q = pInit();
+  pSetCoeff0(q,nInit(1));
+  pSetExpV(q,act);
+  pNext(q) = NULL;
+  last = pNext(last) = q;
+}
+
+static int scMax( int i, scfmon stc, int Nvar)
+{
+  int x, y=stc[0][Nvar];
+  for (; i;)
+  {
+    i--;
+    x = stc[i][Nvar];
+    if (x > y) y = x;
+  }
+  return y;
+}
+
+static int scMin( int i, scfmon stc, int Nvar)
+{
+  int x, y=stc[0][Nvar];
+  for (; i;)
+  {
+    i--;
+    x = stc[i][Nvar];
+    if (x < y) y = x;
+  }
+  return y;
+}
+
+static int scRestrict( int &Nstc, scfmon stc, int Nvar)
+{
+  int x, y;
+  int i, j, Istc = Nstc;
+
+  y = MAX_EXPONENT;
+  for (i=Nstc-1; i>=0; i--)
+  {
+    j = Nvar-1;
+    loop
+    {
+      if(stc[i][j] != 0) break;
+      j--;
+      if (j == 0)
+      {
+        Istc--;
+        x = stc[i][Nvar];
+        if (x < y) y = x;
+        stc[i] = NULL;
+        break;
+      }
+    }
+  }
+  if (Istc < Nstc)
+  {
+    for (i=Nstc-1; i>=0; i--)
+    {
+      if (stc[i] && (stc[i][Nvar] >= y))
+      {
+        Istc--;
+        stc[i] = NULL;
+      }
+    }
+    j = 0;
+    while (stc[j]) j++;
+    i = j+1;
+    for(; i<Nstc; i++)
+    {
+      if (stc[i])
+      {
+        stc[j] = stc[i];
+        j++;
+      }
+    }
+    Nstc = Istc;
+    return y;
+  }
+  else
+    return -1;
+}
+
+static void scAll( int Nvar, int deg)
+{
+  int i;
+  int d = deg;
+  if (d == 0)
+  {
+    for (i=Nvar; i; i--) act[i] = 0;
+    scElKbase();
+    return;
+  }
+  if (Nvar == 1)
+  {
+    act[1] = d;
+    scElKbase();
+    return;
+  }
+  do
+  {
+    act[Nvar] = d;
+    scAll(Nvar-1, deg-d);
+    d--;
+  } while (d >= 0);
+}
+
+static void scAllKbase( int Nvar, int ideg, int deg)
+{
+  do
+  {
+    act[Nvar] = ideg;
+    scAll(Nvar-1, deg-ideg);
+    ideg--;
+  } while (ideg >= 0);
+}
+
+static void scDegKbase( scfmon stc, int Nstc, int Nvar, int deg)
+{
+  int  Ivar, Istc, i, j;
+  scfmon sn;
+  int x, ideg;
+
+  if (deg == 0)
+  {
+    for (i=Nvar; i; i--) act[i] = 0;
+    scElKbase();
+    return;
+  }
+  if (Nvar == 1)
+  {
+    for (i=Nstc-1; i>=0; i--) if(deg >= stc[i][1]) return;
+    act[1] = deg;
+    scElKbase();
+    return;
+  }
+  Ivar = Nvar-1;
+  sn = hGetmem(Nstc, stc, stcmem[Ivar]);
+  x = scRestrict(Nstc, sn, Nvar);
+  if (x <= 0)
+  {
+    if (x == 0) return;
+    ideg = deg;
+  }
+  else
+  {
+    if (deg < x) ideg = deg;
+    else ideg = x-1;
+    if (Nstc == 0)
+    {
+      scAllKbase(Nvar, ideg, deg);
+      return;
+    }
+  }
+  loop
+  {
+    x = scMax(Nstc, sn, Nvar);
+    while (ideg >= x)
+    {
+      act[Nvar] = ideg;
+      scDegKbase(sn, Nstc, Ivar, deg-ideg);
+      ideg--;
+    }
+    if (ideg < 0) return;
+    Istc = Nstc;
+    for (i=Nstc-1; i>=0; i--)
+    {
+      if (ideg < sn[i][Nvar])
+      {
+        Istc--;
+        sn[i] = NULL;
+      }
+    }
+    if (Istc == 0)
+    {
+      scAllKbase(Nvar, ideg, deg);
+      return;
+    }
+    j = 0;
+    while (sn[j]) j++;
+    i = j+1;
+    for (; i<Nstc; i++)
+    {
+      if (sn[i])
+      {
+        sn[j] = sn[i];
+        j++;
+      }
+    }
+    Nstc = Istc;
+  }
+}
+
+static void scInKbase( scfmon stc, int Nstc, int Nvar)
+{
+  int  Ivar, Istc, i, j;
+  scfmon sn;
+  int x, ideg;
+
+  if (Nvar == 1)
+  {
+    ideg = scMin(Nstc, stc, 1);
+    while (ideg > 0)
+    {
+      ideg--;
+      act[1] = ideg;
+      scElKbase();
+    }
+    return;
+  }
+  Ivar = Nvar-1;
+  sn = hGetmem(Nstc, stc, stcmem[Ivar]);
+  x = scRestrict(Nstc, sn, Nvar);
+  if (x == 0) return;
+  ideg = x-1;
+  loop
+  {
+    x = scMax(Nstc, sn, Nvar);
+    while (ideg >= x)
+    {
+      act[Nvar] = ideg;
+      scInKbase(sn, Nstc, Ivar);
+      ideg--;
+    }
+    if (ideg < 0) return;
+    Istc = Nstc;
+    for (i=Nstc-1; i>=0; i--)
+    {
+      if (ideg < sn[i][Nvar])
+      {
+        Istc--;
+        sn[i] = NULL;
+      }
+    }
+    j = 0;
+    while (sn[j]) j++;
+    i = j+1;
+    for (; i<Nstc; i++)
+    {
+      if (sn[i])
+      {
+        sn[j] = sn[i];
+        j++;
+      }
+    }
+    Nstc = Istc;
+  }
+}
+
+static ideal scIdKbase()
+{
+  polyset mm;
+  ideal res;
+  poly p, q = last;
+  int i = pLength(q);
+  res = idInit(i,1);
+  mm = res->m;
+  i = 0;
+  do
+  {
+    mm[i] = q;
+    i++;
+    p = pNext(q);
+    pNext(q) = NULL;
+    q = p;
+  } while (q!=NULL);
+  return res;
+}
+
+extern ideal scKBase(int deg, ideal s, ideal Q)
+{
+  int  i, di;
+  poly p;
+
+  if (deg < 0)
+  {
+    di = scDimInt(s, Q);
+    if (di != 0)
+    {
+      //Werror("KBase not finite");
+      return idInit(1,s->rank);
+    }
+  }
+  stcmem = hCreate(pVariables - 1);
+  hexist = hInit(s, Q, &hNexist);
+  p = last = pInit();
+  /*pNext(p) = NULL;*/
+  act = (scmon)omAlloc((pVariables + 1) * sizeof(int));
+  *act = 0;
+  if (!hNexist)
+  {
+    scAll(pVariables, deg);
+    goto ende;
+  }
+  if (!hisModule)
+  {
+    if (deg < 0) scInKbase(hexist, hNexist, pVariables);
+    else scDegKbase(hexist, hNexist, pVariables, deg);
+  }
+  else
+  {
+    hstc = (scfmon)omAlloc(hNexist * sizeof(scmon));
+    for (i = 1; i <= hisModule; i++)
+    {
+      *act = i;
+      hComp(hexist, hNexist, i, hstc, &hNstc);
+      if (hNstc)
+      {
+        if (deg < 0) scInKbase(hstc, hNstc, pVariables);
+        else scDegKbase(hstc, hNstc, pVariables, deg);
+      }
+      else
+        scAll(pVariables, deg);
+    }
+    omFreeSize((ADDRESS)hstc, hNexist * sizeof(scmon));
+  }
+ende:
+  hDelete(hexist, hNexist);
+  omFreeSize((ADDRESS)act, (pVariables + 1) * sizeof(int));
+  hKill(stcmem, pVariables - 1);
+  pDeleteLm(&p);
+  if (p == NULL)
+    return idInit(1,s->rank);
+  else
+  {
+    last = p;
+    ideal res=scIdKbase();
+    res->rank=s->rank;
+    return res;
+  }
+}
+
+
Index: kernel/hilb.cc
===================================================================
--- kernel/hilb.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/hilb.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,464 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: hilb.cc,v 1.1.1.1 2003-10-06 12:15:53 Singular Exp $ */
+/*
+*  ABSTRACT -  Hilbert series
+*/
+
+#include "mod2.h"
+#include "structs.h"
+#include "febase.h"
+#include "omalloc.h"
+#include "polys.h"
+#include "intvec.h"
+#include "hutil.h"
+#include "stairc.h"
+
+static int  **Qpol;
+static int  *Q0, *Ql;
+static int  hLength;
+
+static int hMinModulweight(intvec *modulweight)
+{
+  int i,j,k;
+
+  if(modulweight==NULL) return 0;
+  j=(*modulweight)[0];
+  for(i=modulweight->rows()-1;i!=0;i--)
+  {
+    k=(*modulweight)[i];
+    if(k<j) j=k;
+  }
+  return j;
+}
+
+static void hHilbEst(scfmon stc, int Nstc, varset var, int Nvar)
+{
+  int  i, j;
+  int  x, y, z = 1;
+  int  *p;
+  for (i = Nvar; i>0; i--)
+  {
+    x = 0;
+    for (j = 0; j < Nstc; j++)
+    {
+      y = stc[j][var[i]];
+      if (y > x)
+        x = y;
+    }
+    z += x;
+    j = i - 1;
+    if (z > Ql[j])
+    {
+      p = (int *)omAlloc(z * sizeof(int));
+      if (Ql[j]!=0)
+      {
+        if (j==0)
+          memcpy(p, Qpol[j], Ql[j] * sizeof(int));
+        omFreeSize((ADDRESS)Qpol[j], Ql[j] * sizeof(int));
+      }
+      if (j==0)
+      {
+        for (x = Ql[j]; x < z; x++)
+          p[x] = 0;
+      }
+      Ql[j] = z;
+      Qpol[j] = p;
+    }
+  }
+}
+
+static int  *hAddHilb(int Nv, int x, int *pol, int *lp)
+{
+  int  l = *lp, ln, i;
+  int  *pon;
+  *lp = ln = l + x;
+  pon = Qpol[Nv];
+  memcpy(pon, pol, l * sizeof(int));
+  if (l > x)
+  {
+    for (i = x; i < l; i++)
+      pon[i] -= pol[i - x];
+    for (i = l; i < ln; i++)
+      pon[i] = -pol[i - x];
+  }
+  else
+  {
+    for (i = l; i < x; i++)
+      pon[i] = 0;
+    for (i = x; i < ln; i++)
+      pon[i] = -pol[i - x];
+  }
+  return pon;
+}
+
+static void hLastHilb(scmon pure, int Nv, varset var, int *pol, int lp)
+{
+  int  l = lp, x, i, j;
+  int  *p, *pl;
+  p = pol;
+  for (i = Nv; i>0; i--)
+  {
+    x = pure[var[i + 1]];
+    if (x!=0)
+      p = hAddHilb(i, x, p, &l);
+  }
+  pl = *Qpol;
+  j = Q0[Nv + 1];
+  for (i = 0; i < l; i++)
+    pl[i + j] += p[i];
+  x = pure[var[1]];
+  if (x!=0)
+  {
+    j += x;
+    for (i = 0; i < l; i++)
+      pl[i + j] -= p[i];
+  }
+  j += l;
+  if (j > hLength)
+    hLength = j;
+}
+
+static void hHilbStep(scmon pure, scfmon stc, int Nstc, varset var,
+ int Nvar, int *pol, int Lpol)
+{
+  int  iv = Nvar -1, ln, a, a0, a1, b, i;
+  int  x, x0;
+  scmon pn;
+  scfmon sn;
+  int  *pon;
+  if (Nstc==0)
+  {
+    hLastHilb(pure, iv, var, pol, Lpol);
+    return;
+  }
+  x = a = 0;
+  pn = hGetpure(pure);
+  sn = hGetmem(Nstc, stc, stcmem[iv]);
+  hStepS(sn, Nstc, var, Nvar, &a, &x);
+  Q0[iv] = Q0[Nvar];
+  ln = Lpol;
+  pon = pol;
+  if (a == Nstc)
+  {
+    x = pure[var[Nvar]];
+    if (x!=0)
+      pon = hAddHilb(iv, x, pon, &ln);
+    hHilbStep(pn, sn, a, var, iv, pon, ln);
+    return;
+  }
+  else
+  {
+    pon = hAddHilb(iv, x, pon, &ln);
+    hHilbStep(pn, sn, a, var, iv, pon, ln);
+  }
+  b = a;
+  x0 = 0;
+  loop
+  {
+    Q0[iv] += (x - x0);
+    a0 = a;
+    x0 = x;
+    hStepS(sn, Nstc, var, Nvar, &a, &x);
+    hElimS(sn, &b, a0, a, var, iv);
+    a1 = a;
+    hPure(sn, a0, &a1, var, iv, pn, &i);
+    hLex2S(sn, b, a0, a1, var, iv, hwork);
+    b += (a1 - a0);
+    ln = Lpol;
+    if (a < Nstc)
+    {
+      pon = hAddHilb(iv, x - x0, pol, &ln);
+      hHilbStep(pn, sn, b, var, iv, pon, ln);
+    }
+    else
+    {
+      x = pure[var[Nvar]];
+      if (x!=0)
+        pon = hAddHilb(iv, x - x0, pol, &ln);
+      else
+        pon = pol;
+      hHilbStep(pn, sn, b, var, iv, pon, ln);
+      return;
+    }
+  }
+}
+
+/*
+*basic routines
+*/
+static void hWDegree(intvec *wdegree)
+{
+  int i, k;
+  int x;
+
+  for (i=pVariables; i; i--)
+  {
+    x = (*wdegree)[i-1];
+    if (x != 1)
+    {
+      for (k=hNexist-1; k>=0; k--)
+      {
+        hexist[k][i] *= x;
+      }
+    }
+  }
+}
+
+static intvec * hSeries(ideal S, intvec *modulweight,
+                int notstc, intvec *wdegree, ideal Q, ring tailRing)
+{
+  intvec *work, *hseries1=NULL;
+  int  mc;
+  int  *p0;
+  int  i, j, k, l, ii, mw;
+  hexist = hInit(S, Q, &hNexist, tailRing);
+  if (hNexist==0)
+  {
+    hseries1=new intvec(2);
+    (*hseries1)[0]=1;
+    (*hseries1)[1]=0;
+    return hseries1;
+  }
+
+  if (wdegree == NULL)
+    hWeight();
+  else
+    hWDegree(wdegree);
+
+  p0 = (int *)omAllocBin(int_bin);
+  *p0 = 1;
+  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  hvar = (varset)omAlloc((pVariables + 1) * sizeof(int));
+  hpure = (scmon)omAlloc((1 + (pVariables * pVariables)) * sizeof(int));
+  stcmem = hCreate(pVariables - 1);
+  Qpol = (int **)omAlloc((pVariables + 1) * sizeof(int *));
+  Ql = (int *)omAlloc0((pVariables + 1) * sizeof(int));
+  Q0 = (int *)omAlloc((pVariables + 1) * sizeof(int));
+  *Qpol = NULL;
+  hLength = k = j = 0;
+  mc = hisModule;
+  if (mc!=0)
+  {
+    mw = hMinModulweight(modulweight);
+    hstc = (scfmon)omAlloc(hNexist * sizeof(scmon));
+  }
+  else
+  {
+    mw = 0;
+    hstc = hexist;
+    hNstc = hNexist;
+  }
+  loop
+  {
+    if (mc!=0)
+    {
+      hComp(hexist, hNexist, mc, hstc, &hNstc);
+      if (modulweight != NULL)
+        j = (*modulweight)[mc-1]-mw;
+    }
+    if (hNstc!=0)
+    {
+      hNvar = pVariables;
+      for (i = hNvar; i>=0; i--)
+        hvar[i] = i;
+      //if (notstc) // TODO: no mon divides another
+        hStaircase(hstc, &hNstc, hvar, hNvar);
+      hSupp(hstc, hNstc, hvar, &hNvar);
+      if (hNvar!=0)
+      {
+        if ((hNvar > 2) && (hNstc > 10))
+          hOrdSupp(hstc, hNstc, hvar, hNvar);
+        hHilbEst(hstc, hNstc, hvar, hNvar);
+        memset(hpure, 0, (pVariables + 1) * sizeof(int));
+        hPure(hstc, 0, &hNstc, hvar, hNvar, hpure, &hNpure);
+        hLexS(hstc, hNstc, hvar, hNvar);
+        Q0[hNvar] = 0;
+        hHilbStep(hpure, hstc, hNstc, hvar, hNvar, p0, 1);
+      }
+    }
+    else
+    {
+      if(*Qpol!=NULL)
+        (**Qpol)++;
+      else
+      {
+        *Qpol = (int *)omAllocBin(int_bin);
+        hLength = *Ql = **Qpol = 1;
+      }
+    }
+    if (*Qpol!=NULL)
+    {
+      i = hLength;
+      while ((i > 0) && ((*Qpol)[i - 1] == 0))
+        i--;
+      if (i > 0)
+      {
+        l = i + j;
+        if (l > k)
+        {
+          work = new intvec(l);
+          for (ii=0; ii<k; ii++)
+            (*work)[ii] = (*hseries1)[ii];
+          if (hseries1 != NULL)
+            delete hseries1;
+          hseries1 = work;
+          k = l;
+        }
+        while (i > 0)
+        {
+          (*hseries1)[i + j - 1] += (*Qpol)[i - 1];
+          (*Qpol)[i - 1] = 0;
+          i--;
+        }
+      }
+    }
+    mc--;
+    if (mc <= 0)
+      break;
+  }
+  if (k==0)
+  {
+    hseries1=new intvec(2);
+    (*hseries1)[0]=0;
+    (*hseries1)[1]=0;
+  }
+  else
+  {
+    l = k+1;
+    while ((*hseries1)[l-2]==0) l--;
+    if (l!=k)
+    {
+      work = new intvec(l);
+      for (ii=l-2; ii>=0; ii--)
+        (*work)[ii] = (*hseries1)[ii];
+      delete hseries1;
+      hseries1 = work;
+    }
+    (*hseries1)[l-1] = mw;
+  }
+  for (i = 0; i <= pVariables; i++)
+  {
+    if (Ql[i]!=0)
+      omFreeSize((ADDRESS)Qpol[i], Ql[i] * sizeof(int));
+  }
+  omFreeSize((ADDRESS)Q0, (pVariables + 1) * sizeof(int));
+  omFreeSize((ADDRESS)Ql, (pVariables + 1) * sizeof(int));
+  omFreeSize((ADDRESS)Qpol, (pVariables + 1) * sizeof(int *));
+  hKill(stcmem, pVariables - 1);
+  omFreeSize((ADDRESS)hpure, (1 + (pVariables * pVariables)) * sizeof(int));
+  omFreeSize((ADDRESS)hvar, (pVariables + 1) * sizeof(int));
+  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
+  hDelete(hexist, hNexist);
+  omFreeBin((ADDRESS)p0,  int_bin);
+  if (hisModule!=0)
+    omFreeSize((ADDRESS)hstc, hNexist * sizeof(scmon));
+  return hseries1;
+}
+
+
+intvec * hHstdSeries(ideal S, intvec *modulweight, intvec *wdegree, ideal Q, ring tailRing)
+{
+  return hSeries(S, modulweight, 0, wdegree, Q, tailRing);
+}
+
+intvec * hFirstSeries(ideal S, intvec *modulweight, ideal Q, intvec *wdegree, ring tailRing)
+{
+  return hSeries(S, modulweight, 1, wdegree, Q, tailRing);
+}
+
+intvec * hSecondSeries(intvec *hseries1)
+{
+  intvec *work, *hseries2;
+  int i, j, k, s, t, l;
+  if (hseries1 == NULL)
+    return NULL;
+  work = new intvec(hseries1);
+  k = l = work->length()-1;
+  s = 0;
+  for (i = k-1; i >= 0; i--)
+    s += (*work)[i];
+  loop
+  {
+    if ((s != 0) || (k == 1))
+      break;
+    s = 0;
+    t = (*work)[k-1];
+    k--;
+    for (i = k-1; i >= 0; i--)
+    {
+      j = (*work)[i];
+      (*work)[i] = -t;
+      s += t;
+      t += j;
+    }
+  }
+  hseries2 = new intvec(k+1);
+  for (i = k-1; i >= 0; i--)
+    (*hseries2)[i] = (*work)[i];
+  (*hseries2)[k] = (*work)[l];
+  delete work;
+  return hseries2;
+}
+
+static void hDegreeSeries(intvec *s1, intvec *s2, int *co, int *mu)
+{
+  int m, i, j, k;
+  *co = *mu = 0;
+  if ((s1 == NULL) || (s2 == NULL))
+    return;
+  i = s1->length();
+  j = s2->length();
+  if (j > i)
+    return;
+  m = 0;
+  for(k=j-2; k>=0; k--)
+    m += (*s2)[k];
+  *mu = m;
+  *co = i - j;
+}
+
+static void hPrintHilb(intvec *hseries)
+{
+  int  i, j, l, k;
+  if (hseries == NULL)
+    return;
+  l = hseries->length()-1;
+  k = (*hseries)[l];
+  for (i = 0; i < l; i++)
+  {
+    j = (*hseries)[i];
+    if (j != 0)
+    {
+      Print("//  %8d t^%d\n", j, i+k);
+    }
+  }
+}
+
+/*
+*caller
+*/
+void hLookSeries(ideal S, intvec *modulweight, ideal Q)
+{
+  int co, mu, l;
+  intvec *hseries2;
+  intvec *hseries1 = hFirstSeries(S, modulweight, Q);
+  hPrintHilb(hseries1);
+  l = hseries1->length()-1;
+  if (l > 1)
+    hseries2 = hSecondSeries(hseries1);
+  else
+    hseries2 = hseries1;
+  hDegreeSeries(hseries1, hseries2, &co, &mu);
+  PrintLn();
+  hPrintHilb(hseries2);
+  if ((l == 1) &&(mu == 0))
+    scPrintDegree(pVariables+1, 0);
+  else
+    scPrintDegree(co, mu);
+  if (l>1)
+    delete hseries1;
+  delete hseries2;
+}
+
Index: kernel/hutil.cc
===================================================================
--- kernel/hutil.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/hutil.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1049 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: hutil.cc,v 1.1.1.1 2003-10-06 12:15:53 Singular Exp $ */
+/*
+* ABSTRACT: Utilities for staircase operations
+*/
+
+#include "mod2.h"
+#include "structs.h"
+#include "febase.h"
+#include "omalloc.h"
+#include "ideals.h"
+#include "polys.h"
+#include "hutil.h"
+
+scfmon hexist, hstc, hrad, hwork;
+scmon hpure, hpur0;
+varset hvar, hsel;
+int  hNexist, hNstc, hNrad, hNvar, hNpure;
+int hisModule;
+monf stcmem, radmem;
+
+// Making a global "security" copy of the allocated exponent vectors
+// is a dirty fix for correct memory disallocation: It would be
+// better, if either the fields of heist are never touched
+// (i.e. changed) except in hInit, or, if hInit would return the
+// "security" copy as well. But then, all the relevant data is held in
+// global variables, so we might do that here, as well.
+static int **hsecure= NULL;
+
+scfmon hInit(ideal S, ideal Q, int *Nexist, ring tailRing)
+{
+  int  sl, ql, i, k = 0;
+  polyset si, qi, ss;
+  scfmon ex, ek;
+  if (tailRing != currRing)
+    hisModule = idRankFreeModule(S, currRing, tailRing);
+  else
+    hisModule = idRankFreeModule(S);
+  if (hisModule < 0)
+    hisModule = 0;
+  if (S)
+  {
+    si = S->m;
+    sl = IDELEMS(S);
+  }
+  else
+  {
+    si = NULL;
+    sl = 0;
+  }
+  if (Q)
+  {
+    qi = Q->m;
+    ql = IDELEMS(Q);
+  }
+  else
+  {
+    qi = NULL;
+    ql = 0;
+  }
+  if (!(sl + ql))
+  {
+    *Nexist = 0;
+    return NULL;
+  }
+  ss = si;
+  for (i = sl; i; i--)
+  {
+    if (*ss!=0)
+      k++;
+    ss++;
+  }
+  ss = qi;
+  for (i = ql; i; i--)
+  {
+    if (*ss!=0)
+      k++;
+    ss++;
+  }
+  *Nexist = k;
+  if (!k)
+    return NULL;
+  ek = ex = (scfmon)omAlloc(k * sizeof(scmon));
+  hsecure = (int**) omAlloc(k * sizeof(scmon));
+  for (i = sl; i>0; i--)
+  {
+    if (*si!=NULL)
+    {
+      *ek = (int*) omAlloc((pVariables+1)*sizeof(int));
+      pGetExpV(*si, *ek);
+      ek++;
+    }
+    si++;
+  }
+  for (i = ql; i; i--)
+  {
+    if (*qi!=NULL)
+    {
+      *ek = (int*) omAlloc((pVariables+1)*sizeof(int));
+      pGetExpV(*qi, *ek);
+      ek++;
+    }
+    qi++;
+  }
+  memcpy(hsecure, ex, k * sizeof(scmon));
+  return ex;
+}
+
+void hWeight()
+{
+  int i, k;
+  int x;
+
+  i = pVariables;
+  loop
+  {
+    if (pWeight(i) != 1) break;
+    i--;
+    if (i == 0) return;
+  }
+  for (i=pVariables; i; i--)
+  {
+    x = pWeight(i);
+    if (x != 1)
+    {
+      for (k=hNexist-1; k>=0; k--)
+      {
+        hexist[k][i] *= x;
+      }
+    }
+  }
+}
+
+void hDelete(scfmon ev, int ev_length)
+{
+  int i;
+
+  for (i=0;i<ev_length;i++)
+    omFreeSize(hsecure[i],(pVariables+1)*sizeof(int));
+  omFreeSize(hsecure, ev_length*sizeof(scmon));
+  omFreeSize(ev,  ev_length*sizeof(scmon));
+}
+
+
+void hComp(scfmon exist, int Nexist, int ak, scfmon stc, int *Nstc)
+{
+  int  i = Nexist, k = 0;
+  scfmon ex = exist, co = stc;
+  for (; i; i--)
+  {
+    if (!(**ex) || ((**ex) == ak))
+    {
+      *co = *ex;
+      co++;
+      k++;
+    }
+    ex++;
+  }
+  *Nstc = k;
+}
+
+
+void hSupp(scfmon stc, int Nstc, varset var, int *Nvar)
+{
+  int  nv, i0, i1, i, j;
+  nv = i0 = *Nvar;
+  i1 = 0;
+  for (i = 1; i <= nv; i++)
+  {
+    j = 0;
+    loop
+    {
+      if (stc[j][i])
+      {
+        i1++;
+        var[i1] = i;
+        break;
+      }
+      j++;
+      if (j == Nstc)
+      {
+        var[i0] = i;
+        i0--;
+        break;
+      }
+    }
+  }
+  *Nvar = i1;
+}
+
+void hOrdSupp(scfmon stc, int Nstc, varset var, int Nvar)
+{
+  int  i, i1, j, jj, k, l;
+  int  x;
+  scmon temp, count;
+  float o, h, g, *v1;
+
+  v1 = (float *)omAlloc(Nvar * sizeof(float));
+  temp = (int *)omAlloc(Nstc * sizeof(int));
+  count = (int *)omAlloc(Nstc * sizeof(int));
+  for (i = 1; i <= Nvar; i++)
+  {
+    i1 = var[i];
+    *temp = stc[0][i1];
+    *count = 1;
+    jj = 1;
+    for (j = 1; j < Nstc; j++)
+    {
+      x = stc[j][i1];
+      k = 0;
+      loop
+      {
+        if (x > temp[k])
+        {
+          k++;
+          if (k == jj)
+          {
+            temp[k] = x;
+            count[k] = 1;
+            jj++;
+            break;
+          }
+        }
+        else if (x < temp[k])
+        {
+          for (l = jj; l > k; l--)
+          {
+            temp[l] = temp[l-1];
+            count[l] = count[l-1];
+          }
+          temp[k] = x;
+          count[k] = 1;
+          jj++;
+          break;
+        }
+        else
+        {
+          count[k]++;
+          break;
+        }
+      }
+    }
+    h = 0.0;
+    o = (float)Nstc/(float)jj;
+    for(j = 0; j < jj; j++)
+    {
+       g = (float)count[j];
+       if (g > o)
+         g -= o;
+       else
+         g = o - g;
+       if (g > h)
+         h = g;
+    }
+    v1[i-1] = h * (float)jj;
+  }
+  omFreeSize((ADDRESS)count, Nstc * sizeof(int));
+  omFreeSize((ADDRESS)temp, Nstc * sizeof(int));
+  for (i = 1; i < Nvar; i++)
+  {
+    i1 = var[i+1];
+    h = v1[i];
+    j = 0;
+    loop
+    {
+      if (h > v1[j])
+      {
+        for (l = i; l > j; l--)
+        {
+          v1[l] = v1[l-1];
+          var[l+1] = var[l];
+        }
+        v1[j] = h;
+        var[j+1] = i1;
+        break;
+      }
+      j++;
+      if (j == i)
+        break;
+    }
+  }
+  omFreeSize((ADDRESS)v1, Nvar * sizeof(float));
+}
+
+
+static void hShrink(scfmon co, int a, int Nco)
+{
+  while ((co[a]!=NULL) && (a<Nco)) a++;
+  int i = a;
+  int j;
+  for (j = a; j < Nco; j++)
+  {
+    if (co[j]!=NULL)
+    {
+      co[i] = co[j];
+      i++;
+    }
+  }
+}
+
+
+void hStaircase(scfmon stc, int *Nstc, varset var, int Nvar)
+{
+  int  nc = *Nstc;
+  if (nc < 2)
+    return;
+  int z = 0;
+  int i = 0;
+  int j = 1;
+  scmon n = stc[1 /*j*/];
+  scmon o = stc[0];
+  int k = Nvar;
+  loop
+  {
+    int k1 = var[k];
+    if (o[k1] > n[k1])
+    {
+      loop
+      {
+        k--;
+        if (k==0)
+        {
+          stc[i] = NULL;
+          z++;
+          break;
+        }
+        else
+        {
+          k1 = var[k];
+          if (o[k1] < n[k1])
+            break;
+        }
+      }
+      k = Nvar;
+    }
+    else if (o[k1] < n[k1])
+    {
+      loop
+      {
+        k--;
+        if (k==0)
+        {
+          stc[j] = NULL;
+          z++;
+          break;
+        }
+        else
+        {
+          k1 = var[k];
+          if (o[k1] > n[k1])
+            break;
+        }
+      }
+      k = Nvar;
+    }
+    else
+    {
+      k--;
+      if (k==0)
+      {
+        stc[j] = NULL;
+        z++;
+        k = Nvar;
+      }
+    }
+    if (k == Nvar)
+    {
+      if (stc[j]==NULL)
+        i = j - 1;
+      loop
+      {
+        i++;
+        if (i == j)
+        {
+          i = -1;
+          j++;
+          if (j < nc)
+            n = stc[j];
+          else
+          {
+            if (z!=0)
+            {
+              *Nstc -= z;
+              hShrink(stc, 0, nc);
+            }
+            return;
+          }
+        }
+        else if (stc[i]!=NULL)
+        {
+          o = stc[i];
+          break;
+        }
+      }
+    }
+  }
+}
+
+
+void hRadical(scfmon rad, int *Nrad, int Nvar)
+{
+  int  nc = *Nrad, z = 0, i, j, k;
+  scmon n, o;
+  if (nc < 2)
+    return;
+  i = 0;
+  j = 1;
+  n = rad[j];
+  o = rad[0];
+  k = Nvar;
+  loop
+  {
+    if ((o[k]!=0) && (n[k]==0))
+    {
+      loop
+      {
+        k--;
+        if (k==0)
+        {
+          rad[i] = NULL;
+          z++;
+          break;
+        }
+        else
+        {
+          if ((o[k]==0) && (n[k]!=0))
+            break;
+        }
+      }
+      k = Nvar;
+    }
+    else if (!o[k] && n[k])
+    {
+      loop
+      {
+        k--;
+        if (!k)
+        {
+          rad[j] = NULL;
+          z++;
+          break;
+        }
+        else
+        {
+          if (o[k] && !n[k])
+            break;
+        }
+      }
+      k = Nvar;
+    }
+    else
+    {
+      k--;
+      if (!k)
+      {
+        rad[j] = NULL;
+        z++;
+        k = Nvar;
+      }
+    }
+    if (k == Nvar)
+    {
+      if (!rad[j])
+        i = j - 1;
+      loop
+      {
+        i++;
+        if (i == j)
+        {
+          i = -1;
+          j++;
+          if (j < nc)
+            n = rad[j];
+          else
+          {
+            if (z)
+            {
+              *Nrad -= z;
+              hShrink(rad, 0, nc);
+            }
+            return;
+          }
+        }
+        else if (rad[i])
+        {
+          o = rad[i];
+          break;
+        }
+      }
+    }
+  }
+}
+
+
+void hLexS(scfmon stc, int Nstc, varset var, int Nvar)
+{
+  if (Nstc < 2)
+    return;
+  int  j = 1, i = 0;
+  scmon n = stc[j];
+  scmon o = stc[0];
+  int k = Nvar;
+  loop
+  {
+    int k1 = var[k];
+    if (o[k1] < n[k1])
+    {
+      i++;
+      if (i < j)
+      {
+        o = stc[i];
+        k = Nvar;
+      }
+      else
+      {
+        j++;
+        if (j < Nstc)
+        {
+          i = 0;
+          o = stc[0];
+          n = stc[j];
+          k = Nvar;
+        }
+        else
+          return;
+      }
+    }
+    else if (o[k1] > n[k1])
+    {
+      int tmp_k;
+      for (tmp_k = j; tmp_k > i; tmp_k--)
+        stc[tmp_k] = stc[tmp_k - 1];
+      stc[i] = n;
+      j++;
+      if (j < Nstc)
+      {
+        i = 0;
+        o = stc[0];
+        n = stc[j];
+        k = Nvar;
+      }
+      else
+        return;
+    }
+    else
+    {
+      k--;
+      if (k<=0) return;
+    }
+  }
+}
+
+
+void hLexR(scfmon rad, int Nrad, varset var, int Nvar)
+{
+  int  j = 1, i = 0, k, k1;
+  scmon n, o;
+  if (Nrad < 2)
+    return;
+  n = rad[j];
+  o = rad[0];
+  k = Nvar;
+  loop
+  {
+    k1 = var[k];
+    if (!o[k1] && n[k1])
+    {
+      i++;
+      if (i < j)
+      {
+        o = rad[i];
+        k = Nvar;
+      }
+      else
+      {
+        j++;
+        if (j < Nrad)
+        {
+          i = 0;
+          o = rad[0];
+          n = rad[j];
+          k = Nvar;
+        }
+        else
+          return;
+      }
+    }
+    else if (o[k1] && !n[k1])
+    {
+      for (k = j; k > i; k--)
+        rad[k] = rad[k - 1];
+      rad[i] = n;
+      j++;
+      if (j < Nrad)
+      {
+        i = 0;
+        o = rad[0];
+        n = rad[j];
+        k = Nvar;
+      }
+      else
+        return;
+    }
+    else
+      k--;
+  }
+}
+
+
+void hPure(scfmon stc, int a, int *Nstc, varset var, int Nvar,
+ scmon pure, int *Npure)
+{
+  int  nc = *Nstc, np = 0, nq = 0, j, i, i1, c, l;
+  scmon x;
+  for (j = a; j < nc; j++)
+  {
+    x = stc[j];
+    i = Nvar;
+    c = 2;
+    l = 0;
+    loop
+    {
+      i1 = var[i];
+      if (x[i1])
+      {
+        c--;
+        if (!c)
+        {
+          l = 0;
+          break;
+        }
+        else if (c == 1)
+          l = i1;
+      }
+      i--;
+      if (!i)
+        break;
+    }
+    if (l)
+    {
+      if (!pure[l])
+      {
+        np++;
+        pure[l] = x[l];
+      }
+      else if (x[l] < pure[l])
+        pure[l] = x[l];
+      stc[j] = NULL;
+      nq++;
+    }
+  }
+  *Npure = np;
+  if (nq!=0)
+  {
+    *Nstc -= nq;
+    hShrink(stc, a, nc);
+  }
+}
+
+
+void hElimS(scfmon stc, int *e1, int a2, int e2, varset var, int Nvar)
+{
+  int  nc = *e1, z = 0, i, j, k, k1;
+  scmon n, o;
+  if (!nc || (a2 == e2))
+    return;
+  j = 0;
+  i = a2;
+  o = stc[i];
+  n = stc[0];
+  k = Nvar;
+  loop
+  {
+    k1 = var[k];
+    if (o[k1] > n[k1])
+    {
+      k = Nvar;
+      i++;
+      if (i < e2)
+        o = stc[i];
+      else
+      {
+        j++;
+        if (j < nc)
+        {
+          i = a2;
+          o = stc[i];
+          n = stc[j];
+        }
+        else
+        {
+          if (z!=0)
+          {
+            *e1 -= z;
+            hShrink(stc, 0, nc);
+          }
+          return;
+        }
+      }
+    }
+    else
+    {
+      k--;
+      if (k==0)
+      {
+        stc[j] = NULL;
+        z++;
+        j++;
+        if (j < nc)
+        {
+          i = a2;
+          o = stc[i];
+          n = stc[j];
+          k = Nvar;
+        }
+        else
+        {
+          if (z!=0)
+          {
+            *e1 -= z;
+            hShrink(stc, 0, nc);
+          }
+          return;
+        }
+      }
+    }
+  }
+}
+
+
+void hElimR(scfmon rad, int *e1, int a2, int e2, varset var, int Nvar)
+{
+  int  nc = *e1, z = 0, i, j, k, k1;
+  scmon n, o;
+  if (!nc || (a2 == e2))
+    return;
+  j = 0;
+  i = a2;
+  o = rad[i];
+  n = rad[0];
+  k = Nvar;
+  loop
+  {
+    k1 = var[k];
+    if (o[k1] && !n[k1])
+    {
+      k = Nvar;
+      i++;
+      if (i < e2)
+        o = rad[i];
+      else
+      {
+        j++;
+        if (j < nc)
+        {
+          i = a2;
+          o = rad[i];
+          n = rad[j];
+        }
+        else
+        {
+          if (z!=0)
+          {
+            *e1 -= z;
+            hShrink(rad, 0, nc);
+          }
+          return;
+        }
+      }
+    }
+    else
+    {
+      k--;
+      if (!k)
+      {
+        rad[j] = NULL;
+        z++;
+        j++;
+        if (j < nc)
+        {
+          i = a2;
+          o = rad[i];
+          n = rad[j];
+          k = Nvar;
+        }
+        else
+        {
+          if (z!=0)
+          {
+            *e1 -= z;
+            hShrink(rad, 0, nc);
+          }
+          return;
+        }
+      }
+    }
+  }
+}
+
+
+void hLex2S(scfmon rad, int e1, int a2, int e2, varset var,
+ int Nvar, scfmon w)
+{
+  int  j0 = 0, j = 0, i = a2, k, k1;
+  scmon n, o;
+  if (!e1)
+  {
+    for (; i < e2; i++)
+      rad[i - a2] = rad[i];
+    return;
+  }  else if (i == e2)
+    return;
+  n = rad[j];
+  o = rad[i];
+  loop
+  {
+    k = Nvar;
+    loop
+    {
+      k1 = var[k];
+      if (o[k1] < n[k1])
+      {
+        w[j0] = o;
+        j0++;
+        i++;
+        if (i < e2)
+        {
+          o = rad[i];
+          break;
+        }
+        else
+        {
+          for (; j < e1; j++)
+          {
+            w[j0] = rad[j];
+            j0++;
+          }
+          memcpy(rad, w, (e1 + e2 - a2) * sizeof(scmon));
+          return;
+        }
+      }
+      else if (o[k1] > n[k1])
+      {
+        w[j0] = n;
+        j0++;
+        j++;
+        if (j < e1)
+        {
+          n = rad[j];
+          break;
+        }
+        else
+        {
+          for (; i < e2; i++)
+          {
+            w[j0] = rad[i];
+            j0++;
+          }
+          memcpy(rad, w, (e1 + e2 - a2) * sizeof(scmon));
+          return;
+        }
+      }
+      k--;
+    }
+  }
+}
+
+
+void hLex2R(scfmon rad, int e1, int a2, int e2, varset var,
+ int Nvar, scfmon w)
+{
+  int  j0 = 0, j = 0, i = a2, k, k1;
+  scmon n, o;
+  if (!e1)
+  {
+    for (; i < e2; i++)
+      rad[i - a2] = rad[i];
+    return;
+  }
+  else if (i == e2)
+    return;
+  n = rad[j];
+  o = rad[i];
+  loop
+  {
+    k = Nvar;
+    loop
+    {
+      k1 = var[k];
+      if (!o[k1] && n[k1])
+      {
+        w[j0] = o;
+        j0++;
+        i++;
+        if (i < e2)
+        {
+          o = rad[i];
+          break;
+        }
+        else
+        {
+          for (; j < e1; j++)
+          {
+            w[j0] = rad[j];
+            j0++;
+          }
+          memcpy(rad, w, (e1 + e2 - a2) * sizeof(scmon));
+          return;
+        }
+      }
+      else if (o[k1] && !n[k1])
+      {
+        w[j0] = n;
+        j0++;
+        j++;
+        if (j < e1)
+        {
+          n = rad[j];
+          break;
+        }
+        else
+        {
+          for (; i < e2; i++)
+          {
+            w[j0] = rad[i];
+            j0++;
+          }
+          memcpy(rad, w, (e1 + e2 - a2) * sizeof(scmon));
+          return;
+        }
+      }
+      k--;
+    }
+  }
+}
+
+
+void hStepS(scfmon stc, int Nstc, varset var, int Nvar, int *a, int *x)
+{
+  int  k1, i;
+  int  y;
+  k1 = var[Nvar];
+  y = *x;
+  i = *a;
+  loop
+  {
+    if (y < stc[i][k1])
+    {
+      *a = i;
+      *x = stc[i][k1];
+      return;
+    }
+    i++;
+    if (i == Nstc)
+    {
+      *a = i;
+      return;
+    }
+  }
+}
+
+
+void hStepR(scfmon rad, int Nrad, varset var, int Nvar, int *a)
+{
+  int  k1, i;
+  k1 = var[Nvar];
+  i = 0;
+  loop
+  {
+    if (rad[i][k1])
+    {
+      *a = i;
+      return;
+    }
+    i++;
+    if (i == Nrad)
+    {
+      *a = i;
+      return;
+    }
+  }
+}
+
+
+monf hCreate(int Nvar)
+{
+  monf xmem;
+  int  i;
+  xmem = (monf)omAlloc((Nvar + 1) * sizeof(monp));
+  for (i = Nvar; i>0; i--)
+  {
+    xmem[i] = (monp)omAlloc(LEN_MON);
+    xmem[i]->mo = NULL;
+  }
+  return xmem;
+}
+
+
+void hKill(monf xmem, int Nvar)
+{
+  int  i;
+  for (i = Nvar; i!=0; i--)
+  {
+    if (xmem[i]->mo!=NULL)
+      omFreeSize((ADDRESS)xmem[i]->mo, xmem[i]->a * sizeof(scmon));
+    omFreeSize((ADDRESS)xmem[i], LEN_MON);
+  }
+  omFreeSize((ADDRESS)xmem, (Nvar + 1) * sizeof(monp));
+}
+
+
+scfmon hGetmem(int lm, scfmon old, monp monmem)
+{
+  scfmon x = monmem->mo;
+  int  lx = monmem->a;
+  if ((x==NULL) || (lm > lx))
+  {
+    if ((x!=NULL)&&(lx>0)) omFreeSize((ADDRESS)x, lx * sizeof(scmon));
+    monmem->mo = x = (scfmon)omAlloc(lm * sizeof(scmon));
+    monmem->a = lm;
+  }
+  memcpy(x, old, lm * sizeof(scmon));
+  return x;
+}
+
+/*
+* a bug in Metrowerks with "lifetime analysis"
+*scmon hGetpure(scmon p)
+*{
+*  scmon p1, pn;
+*  p1 = p + 1;
+*  pn = p1 + pVariables;
+*  memcpy(pn, p1, pVariables * sizeof(int));
+*  return pn - 1;
+*}
+*/
+scmon hGetpure(scmon p)
+{
+  scmon p1 = p;
+  scmon pn;
+  p1++;
+  pn = p1;
+  pn += pVariables;
+  memcpy(pn, p1, pVariables * sizeof(int));
+  return pn - 1;
+}
+
Index: kernel/hutil.h
===================================================================
--- kernel/hutil.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/hutil.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,67 @@
+#ifndef HUTIL_H
+#define HUTIL_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT
+*/
+typedef int * scmon;
+typedef scmon * scfmon;
+typedef int * varset;
+struct monrec;
+typedef struct monrec monh;
+typedef monh * monp;
+typedef monp * monf;
+struct monrec
+{
+  scfmon mo;
+  int a;
+};
+
+#define LEN_MON (sizeof(scfmon) + sizeof(int))
+
+extern scfmon hexist, hstc, hrad, hwork;
+extern scmon hpure, hpur0;
+extern varset hvar, hsel;
+extern int hNexist, hNstc, hNrad, hNvar, hNpure;
+extern monf stcmem, radmem;
+extern int hisModule;
+extern monf stcmem, radmem;
+extern indset ISet, JSet;
+extern int  hCo, hMu, hMu2;
+
+
+scfmon hInit(ideal S, ideal Q, int * Nexist, ring tailRing = currRing);
+void hWeight();
+void hDelete(scfmon ev, int ev_length);
+void hComp(scfmon exist, int Nexist, int ak, scfmon stc, int * Nstc);
+void hSupp(scfmon stc, int Nstc, varset var, int * Nvar);
+void hOrdSupp(scfmon stc, int Nstc, varset var, int Nvar);
+void hStaircase(scfmon stc, int * Nstc, varset var, int Nvar);
+void hRadical(scfmon rad, int * Nrad, int Nvar);
+void hLexS(scfmon stc, int Nstc, varset var, int Nvar);
+void hLexR(scfmon rad, int Nrad, varset var, int Nvar);
+void hPure(scfmon stc, int a, int *Nstc, varset var, int Nvar,
+ scmon pure, int *Npure);
+void hElimS(scfmon stc, int * e1, int a2, int e2,varset var, int Nvar);
+void hElimR(scfmon rad, int * e1, int a2, int e2,varset var, int Nvar);
+void hLex2S(scfmon stc, int e1, int a2, int e2,varset var,
+ int Nvar, scfmon w);
+void hLex2R(scfmon rad, int e1, int a2, int e2,varset var,
+ int Nvar, scfmon w);
+void hStepS(scfmon stc, int Nstc, varset var, int Nvar,int *a, int *x);
+void hStepR(scfmon rad, int Nrad, varset var, int Nvar,int *a);
+monf hCreate(int Nvar);
+void hKill(monf xmem, int Nvar);
+scfmon hGetmem(int lm, scfmon old, monp monmem);
+scmon hGetpure(scmon p);
+void hDimSolve(scmon pure, int Npure, scfmon rad, int Nrad,
+ varset var, int Nvar);
+void hIndMult(scmon pure, int Npure, scfmon rad, int Nrad,
+ varset var, int Nvar);
+void hIndAllMult(scmon pure, int Npure, scfmon rad, int Nrad,
+ varset var, int Nvar);
+
+
+#endif
Index: kernel/ideals.cc
===================================================================
--- kernel/ideals.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/ideals.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,3594 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: ideals.cc,v 1.1.1.1 2003-10-06 12:15:53 Singular Exp $ */
+/*
+* ABSTRACT - all basic methods to manipulate ideals
+*/
+
+/* includes */
+#include "mod2.h"
+#include "structs.h"
+#include "omalloc.h"
+#include "febase.h"
+#include "numbers.h"
+#include "polys.h"
+#include "ring.h"
+#include "kstd1.h"
+#include "matpol.h"
+#include "weight.h"
+#include "intvec.h"
+#include "syz.h"
+#include "sparsmat.h"
+#include "ideals.h"
+#include "prCopy.h"
+
+
+/* #define WITH_OLD_MINOR */
+#define pCopy_noCheck(p) pCopy(p)
+
+static poly * idpower;
+/*collects the monomials in makemonoms, must be allocated befor*/
+static int idpowerpoint;
+/*index of the actual monomial in idpower*/
+static poly * givenideal;
+/*the ideal from which a power is computed*/
+
+/*0 implementation*/
+
+/*2
+* initialise an ideal
+*/
+#ifdef PDEBUG
+ideal idDBInit(int idsize, int rank, char *f, int l)
+#else
+ideal idInit(int idsize, int rank)
+#endif
+{
+  /*- initialise an ideal -*/
+  ideal hh = (ideal )omAllocBin(sip_sideal_bin);
+  hh->nrows = 1;
+  hh->rank = rank;
+  IDELEMS(hh) = idsize;
+  if (idsize>0)
+  {
+    hh->m = (poly *)omAlloc0(idsize*sizeof(poly));
+  }
+  else
+    hh->m=NULL;
+  return hh;
+}
+
+//#ifndef __OPTIMIZE__
+// this is mainly for outputting an ideal within the debugger
+void idShow(ideal id)
+{
+  Print("Module of rank %d,real rank %d and %d generators.\n",
+         id->rank,idRankFreeModule(id),IDELEMS(id));
+  for (int i=0;i<id->ncols*id->nrows;i++)
+  {
+    if (id->m[i]!=NULL)
+    {
+      Print("generator %d: ",i);pWrite(id->m[i]);
+    }
+  }
+}
+//#endif
+
+/*2
+* initialise the maximal ideal (at 0)
+*/
+ideal idMaxIdeal (void)
+{
+  int l;
+  ideal hh=NULL;
+
+  hh=idInit(pVariables,1);
+  for (l=0; l<pVariables; l++)
+  {
+    hh->m[l] = pOne();
+    pSetExp(hh->m[l],l+1,1);
+    pSetm(hh->m[l]);
+  }
+  return hh;
+}
+
+/*2
+* deletes an ideal/matrix
+*/
+void id_Delete (ideal * h, ring r)
+{
+  int j,elems;
+  if (*h == NULL)
+    return;
+  elems=j=(*h)->nrows*(*h)->ncols;
+  if (j>0)
+  {
+    do
+    {
+      p_Delete(&((*h)->m[--j]), r);
+    }
+    while (j>0);
+    omFreeSize((ADDRESS)((*h)->m),sizeof(poly)*elems);
+  }
+  omFreeBin((ADDRESS)*h, sip_sideal_bin);
+  *h=NULL;
+}
+
+
+/*2
+* Shallowdeletes an ideal/matrix
+*/
+void id_ShallowDelete (ideal *h, ring r)
+{
+  int j,elems;
+  if (*h == NULL)
+    return;
+  elems=j=(*h)->nrows*(*h)->ncols;
+  if (j>0)
+  {
+    do
+    {
+      p_ShallowDelete(&((*h)->m[--j]), r);
+    }
+    while (j>0);
+    omFreeSize((ADDRESS)((*h)->m),sizeof(poly)*elems);
+  }
+  omFreeBin((ADDRESS)*h, sip_sideal_bin);
+  *h=NULL;
+}
+
+/*2
+*gives an ideal the minimal possible size
+*/
+void idSkipZeroes (ideal ide)
+{
+  int k;
+  int j = -1;
+  BOOLEAN change=FALSE;
+  for (k=0; k<IDELEMS(ide); k++)
+  {
+    if (ide->m[k] != NULL)
+    {
+      j++;
+      if (change)
+      {
+        ide->m[j] = ide->m[k];
+      }
+    }
+    else
+    {
+      change=TRUE;
+    }
+  }
+  if (change)
+  {
+    if (j == -1)
+      j = 0;
+    else
+    {
+      for (k=j+1; k<IDELEMS(ide); k++)
+        ide->m[k] = NULL;
+    }
+    pEnlargeSet(&(ide->m),IDELEMS(ide),j+1-IDELEMS(ide));
+    IDELEMS(ide) = j+1;
+  }
+}
+
+/*2
+* ideal id = (id[i])
+* result is leadcoeff(id[i]) = 1
+*/
+void idNorm(ideal id)
+{
+  for (int i=0; i<IDELEMS(id); i++)
+  {
+    if (id->m[i] != NULL)
+    {
+      pNorm(id->m[i]);
+    }
+  }
+}
+
+/*2
+* ideal id = (id[i]), c any number
+* if id[i] = c*id[j] then id[j] is deleted for j > i
+*/
+void idDelMultiples(ideal id)
+{
+  int i, j, t;
+  int k = IDELEMS(id), l = k;
+  for (i=k-2; i>=0; i--)
+  {
+    if (id->m[i]!=NULL)
+    {
+      for (j=l-1; j>i; j--)
+      {
+        if ((id->m[j]!=NULL)
+        && (pComparePolys(id->m[i], id->m[j])))
+        {
+          pDelete(&id->m[j]);
+          l--;
+          for(t=j; t<l; t++)
+          {
+            id->m[t] = id->m[t+1];
+          }
+        }
+      }
+    }
+  }
+  if (l != k)
+  {
+    pEnlargeSet(&id->m, k, l-k);
+    IDELEMS(id) = l;
+  }
+}
+
+/*2
+* ideal id = (id[i])
+* if id[i] = id[j] then id[j] is deleted for j > i
+*/
+void idDelEquals(ideal id)
+{
+  int i, j, t;
+  int k = IDELEMS(id), l = k;
+  for (i=k-2; i>=0; i--)
+  {
+    for (j=l-1; j>i; j--)
+    {
+      if (pEqualPolys(id->m[i], id->m[j]))
+      {
+        pDelete(&id->m[j]);
+        l--;
+        for(t=j; t<l; t++)
+        {
+          id->m[t] = id->m[t+1];
+        }
+      }
+    }
+  }
+  if (l != k)
+  {
+    pEnlargeSet(&id->m, k, l-k);
+    IDELEMS(id) = l;
+  }
+}
+
+//
+// Delete id[j], if Lm(j) == Lm(i) and j > i
+//
+void idDelLmEquals(ideal id)
+{
+  int i, j, t;
+  int k = IDELEMS(id), l = k;
+  for (i=k-2; i>=0; i--)
+  {
+    for (j=l-1; j>i; j--)
+    {
+      if (id->m[i] != NULL && id->m[j] != NULL && pLmEqual(id->m[i], id->m[j]))
+      {
+        pDelete(&id->m[j]);
+        l--;
+        for(t=j; t<l; t++)
+        {
+          id->m[t] = id->m[t+1];
+        }
+      }
+    }
+  }
+  if (l != k)
+  {
+    pEnlargeSet(&id->m, k, l-k);
+    IDELEMS(id) = l;
+  }
+}
+
+void idDelDiv(ideal id)
+{
+  int i, j, t;
+  int k = IDELEMS(id), l = k;
+  for (i=k-2; i>=0; i--)
+  {
+    for (j=l-1; j>i; j--)
+    {
+
+      if (((id->m[j] != NULL) && pDivisibleBy(id->m[i], id->m[j])) ||
+          (id->m[i] == NULL && id->m[j] == NULL))
+      {
+        pDelete(&id->m[j]);
+        l--;
+        for(t=j; t<l; t++)
+        {
+          id->m[t] = id->m[t+1];
+        }
+      }
+    }
+  }
+  if (l != k)
+  {
+    pEnlargeSet(&id->m, k, l-k);
+    IDELEMS(id) = l;
+  }
+}
+
+/*2
+*test if the ideal has only constant polynomials
+*/
+BOOLEAN idIsConstant(ideal id)
+{
+  int k;
+  for (k = IDELEMS(id)-1; k>=0; k--)
+  {
+    if (pIsConstantPoly(id->m[k]) == FALSE)
+      return FALSE;
+  }
+  return TRUE;
+}
+
+/*2
+* copy an ideal
+*/
+#ifdef PDEBUG
+ideal idDBCopy(ideal h1,char *f,int l)
+#else
+ideal idCopy (ideal h1)
+#endif
+{
+  int i;
+  ideal h2;
+
+#ifdef PDEBUG
+  idDBTest(h1,PDEBUG,f,l);
+#endif
+//#ifdef TEST
+  if (h1 == NULL)
+  {
+#ifdef PDEBUG
+    h2=idDBInit(1,1,f,l);
+#else
+    h2=idInit(1,1);
+#endif
+  }
+  else
+//#endif
+  {
+#ifdef PDEBUG
+    h2=idDBInit(IDELEMS(h1),h1->rank,f,l);
+#else
+    h2=idInit(IDELEMS(h1),h1->rank);
+#endif
+    for (i=IDELEMS(h1)-1; i>=0; i--)
+      h2->m[i] = pCopy(h1->m[i]);
+  }
+  return h2;
+}
+
+#ifdef PDEBUG
+void idDBTest(ideal h1, int level, char *f,int l)
+{
+  int i;
+
+  if (h1 != NULL)
+  {
+    // assume(IDELEMS(h1) > 0); for ideal/module, does not apply to matrix
+    omCheckAddrSize(h1,sizeof(*h1));
+    omdebugAddrSize(h1->m,h1->ncols*h1->nrows*sizeof(poly));
+    /* to be able to test matrices: */
+    for (i=(h1->ncols*h1->nrows)-1; i>=0; i--)
+      _p_Test(h1->m[i], currRing, level);
+    int new_rk=idRankFreeModule(h1);
+    if(new_rk > h1->rank)
+    {
+      dReportError("wrong rank %d (should be %d) in %s:%d\n",
+                   h1->rank, new_rk, f,l);
+      omPrintAddrInfo(stderr, h1, " for ideal");
+      h1->rank=new_rk;
+    }
+  }
+}
+#endif
+
+/*3
+* for idSort: compare a and b revlex inclusive module comp.
+*/
+static int pComp_RevLex(poly a, poly b,BOOLEAN nolex)
+{
+  if (b==NULL) return 1;
+  if (a==NULL) return -1;
+
+  if (nolex) return pLmCmp(a,b);
+  int l=pVariables;
+  while ((l>0) && (pGetExp(a,l)==pGetExp(b,l))) l--;
+  if (l==0)
+  {
+    if (pGetComp(a)==pGetComp(b)) return 0;
+    if (pGetComp(a)>pGetComp(b)) return 1;
+  }
+  else if (pGetExp(a,l)>pGetExp(b,l))
+    return 1;
+  return -1;
+}
+
+/*2
+*sorts the ideal w.r.t. the actual ringordering
+*uses lex-ordering when nolex = FALSE
+*/
+intvec *idSort(ideal id,BOOLEAN nolex)
+{
+  poly p,q;
+  intvec * result = new intvec(IDELEMS(id));
+  int i, j, actpos=0, newpos, l;
+  int diff, olddiff, lastcomp, newcomp;
+  BOOLEAN notFound;
+
+  for (i=0;i<IDELEMS(id);i++)
+  {
+    if (id->m[i]!=NULL)
+    {
+      notFound = TRUE;
+      newpos = actpos / 2;
+      diff = (actpos+1) / 2;
+      diff = (diff+1) / 2;
+      lastcomp = pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex);
+      if (lastcomp<0)
+      {
+        newpos -= diff;
+      }
+      else if (lastcomp>0)
+      {
+        newpos += diff;
+      }
+      else
+      {
+        notFound = FALSE;
+      }
+      //while ((newpos>=0) && (newpos<actpos) && (notFound))
+      while (notFound && (newpos>=0) && (newpos<actpos))
+      {
+        newcomp = pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex);
+        olddiff = diff;
+        if (diff>1)
+        {
+          diff = (diff+1) / 2;
+          if ((newcomp==1)
+          && (actpos-newpos>1)
+          && (diff>1)
+          && (newpos+diff>=actpos))
+          {
+            diff = actpos-newpos-1;
+          }
+          else if ((newcomp==-1)
+          && (diff>1)
+          && (newpos<diff))
+          {
+            diff = newpos;
+          }
+        }
+        if (newcomp<0)
+        {
+          if ((olddiff==1) && (lastcomp>0))
+            notFound = FALSE;
+          else
+            newpos -= diff;
+        }
+        else if (newcomp>0)
+        {
+          if ((olddiff==1) && (lastcomp<0))
+          {
+            notFound = FALSE;
+            newpos++;
+          }
+          else
+          {
+            newpos += diff;
+          }
+        }
+        else
+        {
+          notFound = FALSE;
+        }
+        lastcomp = newcomp;
+        if (diff==0) notFound=FALSE; /*hs*/
+      }
+      if (newpos<0) newpos = 0;
+      if (newpos>actpos) newpos = actpos;
+      while ((newpos<actpos) && (pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex)==0))
+        newpos++;
+      for (j=actpos;j>newpos;j--)
+      {
+        (*result)[j] = (*result)[j-1];
+      }
+      (*result)[newpos] = i;
+      actpos++;
+    }
+  }
+  for (j=0;j<actpos;j++) (*result)[j]++;
+  return result;
+}
+
+/*2
+* concat the lists h1 and h2 without zeros
+*/
+ideal idSimpleAdd (ideal h1,ideal h2)
+{
+  int i,j,r,l;
+  ideal result;
+
+  if (h1==NULL) return idCopy(h2);
+  if (h2==NULL) return idCopy(h1);
+  j = IDELEMS(h1)-1;
+  while ((j >= 0) && (h1->m[j] == NULL)) j--;
+  i = IDELEMS(h2)-1;
+  while ((i >= 0) && (h2->m[i] == NULL)) i--;
+  r = si_max(h1->rank,h2->rank);
+  if (i+j==(-2))
+    return idInit(1,r);
+  else
+    result=idInit(i+j+2,r);
+  for (l=j; l>=0; l--)
+  {
+    result->m[l] = pCopy(h1->m[l]);
+  }
+  r = i+j+1;
+  for (l=i; l>=0; l--, r--)
+  {
+    result->m[r] = pCopy(h2->m[l]);
+  }
+  return result;
+}
+
+/*2
+* h1 + h2
+*/
+ideal idAdd (ideal h1,ideal h2)
+{
+  ideal result = idSimpleAdd(h1,h2);
+  ideal tmp = idCompactify(result);
+
+  idDelete(&result);
+  return tmp;
+}
+
+/*2
+* h1 * h2
+*/
+ideal  idMult (ideal h1,ideal  h2)
+{
+  int i,j,k;
+  ideal  hh;
+
+  j = IDELEMS(h1);
+  while ((j > 0) && (h1->m[j-1] == NULL)) j--;
+  i = IDELEMS(h2);
+  while ((i > 0) && (h2->m[i-1] == NULL)) i--;
+  j = j * i;
+  if (j == 0)
+    hh = idInit(1,1);
+  else
+    hh=idInit(j,1);
+  if (h1->rank<h2->rank)
+    hh->rank = h2->rank;
+  else
+    hh->rank = h1->rank;
+  if (j==0) return hh;
+  k = 0;
+  for (i=0; i<IDELEMS(h1); i++)
+  {
+    if (h1->m[i] != NULL)
+    {
+      for (j=0; j<IDELEMS(h2); j++)
+      {
+        if (h2->m[j] != NULL)
+        {
+          hh->m[k] = ppMult_qq(h1->m[i],h2->m[j]);
+          k++;
+        }
+      }
+    }
+  }
+  {
+    ideal tmp = idCompactify(hh);
+    idDelete(&hh);
+    return tmp;
+    //return hh;
+  }
+}
+
+/*2
+*returns true if h is the zero ideal
+*/
+BOOLEAN idIs0 (ideal h)
+{
+  int i;
+
+  if (h == NULL) return TRUE;
+  i = IDELEMS(h);
+  while ((i > 0) && (h->m[i-1] == NULL))
+  {
+    i--;
+  }
+  if (i == 0)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+/*2
+* return the maximal component number found in any polynomial in s
+*/
+long idRankFreeModule (ideal s, ring lmRing, ring tailRing)
+{
+  if (s!=NULL)
+  {
+    int  j=0;
+
+    if (rRing_has_Comp(tailRing) && rRing_has_Comp(lmRing))
+    {
+      int  l=IDELEMS(s);
+      poly *p=s->m;
+      int  k;
+      for (; l != 0; l--)
+      {
+        if (*p!=NULL)
+        {
+          pp_Test(*p, lmRing, tailRing);
+          k = p_MaxComp(*p, lmRing, tailRing);
+          if (k>j) j = k;
+        }
+        p++;
+      }
+    }
+    return j;
+  }
+  return -1;
+}
+
+BOOLEAN idIsModule(ideal id, ring r)
+{
+  if (id != NULL && rRing_has_Comp(r))
+  {
+    int j, l = IDELEMS(id);
+    for (j=0; j<l; j++)
+    {
+      if (id->m[j] != NULL && p_GetComp(id->m[j], r) > 0) return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+
+/*2
+*returns true if id is homogenous with respect to the aktual weights
+*/
+BOOLEAN idHomIdeal (ideal id, ideal Q)
+{
+  int i;
+  BOOLEAN     b;
+  if ((id == NULL) || (IDELEMS(id) == 0)) return TRUE;
+  i = 0;
+  b = TRUE;
+  while ((i < IDELEMS(id)) && b)
+  {
+    b = pIsHomogeneous(id->m[i]);
+    i++;
+  }
+  if ((b) && (Q!=NULL) && (IDELEMS(Q)>0))
+  {
+    i=0;
+    while ((i < IDELEMS(Q)) && b)
+    {
+      b = pIsHomogeneous(Q->m[i]);
+      i++;
+    }
+  }
+  return b;
+}
+
+/*2
+*returns a minimized set of generators of h1
+*/
+ideal idMinBase (ideal h1)
+{
+  ideal h2, h3,h4,e;
+  int j,k;
+  int i,l,ll;
+  intvec * wth;
+  BOOLEAN homog;
+
+  homog = idHomModule(h1,currQuotient,&wth);
+  if ((currRing->OrdSgn == 1) && (!homog))
+  {
+    Warn("minbase applies only to the local or homogeneous case");
+    e=idCopy(h1);
+    return e;
+  }
+  if ((currRing->OrdSgn == 1) && (homog))
+  {
+    ideal re=kMin_std(h1,currQuotient,(tHomog)homog,&wth,h2,NULL,0,3);
+    idDelete(&re);
+    return h2;
+  }
+  e=idInit(1,h1->rank);
+  if (idIs0(h1))
+  {
+    return e;
+  }
+  pEnlargeSet(&(e->m),IDELEMS(e),15);
+  IDELEMS(e) = 16;
+  h2 = kStd(h1,currQuotient,isNotHomog,NULL);
+  h3 = idMaxIdeal();
+  h4=idMult(h2,h3);
+  idDelete(&h3);
+  h3=kStd(h4,currQuotient,isNotHomog,NULL);
+  k = IDELEMS(h3);
+  while ((k > 0) && (h3->m[k-1] == NULL)) k--;
+  j = -1;
+  l = IDELEMS(h2);
+  while ((l > 0) && (h2->m[l-1] == NULL)) l--;
+  for (i=l-1; i>=0; i--)
+  {
+    if (h2->m[i] != NULL)
+    {
+      ll = 0;
+      while ((ll < k) && ((h3->m[ll] == NULL)
+      || !pDivisibleBy(h3->m[ll],h2->m[i])))
+        ll++;
+      if (ll >= k)
+      {
+        j++;
+        if (j > IDELEMS(e)-1)
+        {
+          pEnlargeSet(&(e->m),IDELEMS(e),16);
+          IDELEMS(e) += 16;
+        }
+        e->m[j] = pCopy(h2->m[i]);
+      }
+    }
+  }
+  idDelete(&h2);
+  idDelete(&h3);
+  idDelete(&h4);
+  if (currQuotient!=NULL)
+  {
+    h3=idInit(1,e->rank);
+    h2=kNF(h3,currQuotient,e);
+    idDelete(&h3);
+    idDelete(&e);
+    e=h2;
+  }
+  idSkipZeroes(e);
+  return e;
+}
+
+/*2
+*the minimal index of used variables - 1
+*/
+int pLowVar (poly p)
+{
+  int k,l,lex;
+
+  if (p == NULL) return -1;
+
+  k = 32000;/*a very large dummy value*/
+  while (p != NULL)
+  {
+    l = 1;
+    lex = pGetExp(p,l);
+    while ((l < pVariables) && (lex == 0))
+    {
+      l++;
+      lex = pGetExp(p,l);
+    }
+    l--;
+    if (l < k) k = l;
+    pIter(p);
+  }
+  return k;
+}
+
+/*3
+*multiplies p with t (!cas) or  (t-1)
+*the index of t is:1, so we have to shift all variables
+*p is NOT in the actual ring, it has no t
+*/
+static poly pMultWithT (poly p,BOOLEAN cas)
+{
+  /*qp is the working pointer in p*/
+  /*result is the result, qresult is the working pointer*/
+  /*pp is p in the actual ring(shifted), qpp the working pointer*/
+  poly result,qp,pp;
+  poly qresult=NULL;
+  poly qpp=NULL;
+  int  i,j,lex;
+  number n;
+
+  pp = NULL;
+  result = NULL;
+  qp = p;
+  while (qp != NULL)
+  {
+    i = 0;
+    if (result == NULL)
+    {/*first monomial*/
+      result = pInit();
+      qresult = result;
+    }
+    else
+    {
+      qresult->next = pInit();
+      pIter(qresult);
+    }
+    for (j=pVariables-1; j>0; j--)
+    {
+      lex = pGetExp(qp,j);
+      pSetExp(qresult,j+1,lex);/*copy all variables*/
+    }
+    lex = pGetComp(qp);
+    pSetComp(qresult,lex);
+    n=nCopy(pGetCoeff(qp));
+    pSetCoeff0(qresult,n);
+    qresult->next = NULL;
+    pSetm(qresult);
+    /*qresult is now qp brought into the actual ring*/
+    if (cas)
+    { /*case: mult with t-1*/
+      pSetExp(qresult,1,0);
+      pSetm(qresult);
+      if (pp == NULL)
+      { /*first monomial*/
+        pp = pCopy(qresult);
+        qpp = pp;
+      }
+      else
+      {
+        qpp->next = pCopy(qresult);
+        pIter(qpp);
+      }
+      pGetCoeff(qpp)=nNeg(pGetCoeff(qpp));
+      /*now qpp contains -1*qp*/
+    }
+    pSetExp(qresult,1,1);/*this is mult. by t*/
+    pSetm(qresult);
+    pIter(qp);
+  }
+  /*
+  *now p is processed:
+  *result contains t*p
+  * if cas: pp contains -1*p (in the new ring)
+  */
+  if (cas)  qresult->next = pp;
+  /*  else      qresult->next = NULL;*/
+  return result;
+}
+
+/*3
+*deletes the place of t in p (t: variable with index 1)
+*p is NOT in the actual ring: it has pVariables+1 variables
+*/
+static poly pDivByT (poly * p,int size)
+{
+
+  poly result=NULL,
+       resultp=NULL , /** working pointer in result **/
+       pp;
+  int  i,j;
+
+  while (*p != NULL)
+  {
+    i = 0;
+    if (result == NULL)
+    {/*the first monomial*/
+      result = pInit();
+      resultp = result;
+      resultp->next = NULL;
+    }
+    else
+    {
+      resultp->next = pInit();
+      pIter(resultp);
+      resultp->next = NULL;
+    }
+    for (j=1; j<=pVariables; j++)
+    {
+      pSetExp(resultp,j,pGetExp(*p,j+1));
+    }
+    pSetComp(resultp,pGetComp(*p));
+    pSetCoeff0(resultp,pGetCoeff(*p));
+    pSetm(resultp);
+    pp = (*p)->next;
+    omFreeSize((ADDRESS)*p,size);
+    *p = pp;
+  }
+  return result;
+}
+
+/*2
+*dehomogenized the generators of the ideal id1 with the leading
+*monomial of p replaced by n
+*/
+ideal idDehomogen (ideal id1,poly p,number n)
+{
+  int i;
+  ideal result;
+
+  if (idIs0(id1))
+  {
+    return idInit(1,id1->rank);
+  }
+  result=idInit(IDELEMS(id1),id1->rank);
+  for (i=0; i<IDELEMS(id1); i++)
+  {
+    result->m[i] = pDehomogen(id1->m[i],p,n);
+  }
+  return result;
+}
+
+/*2
+* verschiebt die Indizees der Modulerzeugenden um i
+*/
+void pShift (poly * p,int i)
+{
+  poly qp1 = *p,qp2 = *p;/*working pointers*/
+  int     j = pMaxComp(*p),k = pMinComp(*p);
+
+  if (j+i < 0) return ;
+  while (qp1 != NULL)
+  {
+    if ((pGetComp(qp1)+i > 0) || ((j == -i) && (j == k)))
+    {
+      pSetComp(qp1,pGetComp(qp1)+i);
+      pSetmComp(qp1);
+      qp2 = qp1;
+      pIter(qp1);
+    }
+    else
+    {
+      if (qp2 == *p)
+      {
+        pIter(*p);
+        pDeleteLm(&qp2);
+        qp2 = *p;
+        qp1 = *p;
+      }
+      else
+      {
+        qp2->next = qp1->next;
+        pDeleteLm(&qp1);
+        qp1 = qp2->next;
+      }
+    }
+  }
+}
+
+/*2
+*initialized a field with r numbers between beg and end for the
+*procedure idNextChoise
+*/
+void idInitChoise (int r,int beg,int end,BOOLEAN  *endch,int * choise)
+{
+  /*returns the first choise of r numbers between beg and end*/
+  int i;
+  for (i=0; i<r; i++)
+  {
+    choise[i] = 0;
+  }
+  if (r <= end-beg+1)
+    for (i=0; i<r; i++)
+    {
+      choise[i] = beg+i;
+    }
+  if (r > end-beg+1)
+    *endch = TRUE;
+  else
+    *endch = FALSE;
+}
+
+/*2
+*returns the next choise of r numbers between beg and end
+*/
+void idGetNextChoise (int r,int end,BOOLEAN  *endch,int * choise)
+{
+  int i = r-1,j;
+  while ((i >= 0) && (choise[i] == end))
+  {
+    i--;
+    end--;
+  }
+  if (i == -1)
+    *endch = TRUE;
+  else
+  {
+    choise[i]++;
+    for (j=i+1; j<r; j++)
+    {
+      choise[j] = choise[i]+j-i;
+    }
+    *endch = FALSE;
+  }
+}
+
+/*2
+*takes the field choise of d numbers between beg and end, cancels the t-th
+*entree and searches for the ordinal number of that d-1 dimensional field
+* w.r.t. the algorithm of construction
+*/
+int idGetNumberOfChoise(int t, int d, int begin, int end, int * choise)
+{
+  int * localchoise,i,result=0;
+  BOOLEAN b=FALSE;
+
+  if (d<=1) return 1;
+  localchoise=(int*)omAlloc((d-1)*sizeof(int));
+  idInitChoise(d-1,begin,end,&b,localchoise);
+  while (!b)
+  {
+    result++;
+    i = 0;
+    while ((i<t) && (localchoise[i]==choise[i])) i++;
+    if (i>=t)
+    {
+      i = t+1;
+      while ((i<d) && (localchoise[i-1]==choise[i])) i++;
+      if (i>=d)
+      {
+        omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
+        return result;
+      }
+    }
+    idGetNextChoise(d-1,end,&b,localchoise);
+  }
+  omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
+  return 0;
+}
+
+/*2
+*computes the binomial coefficient
+*/
+int binom (int n,int r)
+{
+  int i,result;
+
+  if (r==0) return 1;
+  if (n-r<r) return binom(n,n-r);
+  result = n-r+1;
+  for (i=2;i<=r;i++)
+  {
+    result *= n-r+i;
+    if (result<0)
+    {
+      WarnS("overflow in binomials");
+      return 0;
+    }
+    result /= i;
+  }
+  return result;
+}
+
+/*2
+*the free module of rank i
+*/
+ideal idFreeModule (int i)
+{
+  int j;
+  ideal h;
+
+  h=idInit(i,i);
+  for (j=0; j<i; j++)
+  {
+    h->m[j] = pOne();
+    pSetComp(h->m[j],j+1);
+    pSetmComp(h->m[j]);
+  }
+  return h;
+}
+
+/*2
+* h3 := h1 intersect h2
+*/
+ideal idSect (ideal h1,ideal h2)
+{
+  ideal first=h2,second=h1,temp,temp1,result;
+  int i,j,k,flength,slength,length,rank=si_min(h1->rank,h2->rank);
+  intvec *w;
+  poly p,q;
+
+  if ((idIs0(h1)) && (idIs0(h2)))  return idInit(1,rank);
+  if (IDELEMS(h1)<IDELEMS(h2))
+  {
+    first = h1;
+    second = h2;
+  }
+  flength = idRankFreeModule(first);
+  slength = idRankFreeModule(second);
+  length  = si_max(flength,slength);
+  if (length==0)
+  {
+    length = 1;
+  }
+  j = IDELEMS(first);
+  temp = idInit(j /*IDELEMS(first)*/,length+j);
+
+  ring orig_ring=currRing;
+  ring syz_ring=rCurrRingAssure_SyzComp();
+  rSetSyzComp(length);
+
+  while ((j>0) && (first->m[j-1]==NULL)) j--;
+  k = 0;
+  for (i=0;i<j;i++)
+  {
+    if (first->m[i]!=NULL)
+    {
+      if (syz_ring==orig_ring)
+        temp->m[k] = pCopy(first->m[i]);
+      else
+        temp->m[k] = prCopyR(first->m[i], orig_ring);
+      q = pOne();
+      pSetComp(q,i+1+length);
+      pSetmComp(q);
+      if (flength==0) pShift(&(temp->m[k]),1);
+      p = temp->m[k];
+      while (pNext(p)!=NULL) pIter(p);
+      pNext(p) = q;
+      k++;
+    }
+  }
+  pEnlargeSet(&(temp->m),IDELEMS(temp),j+IDELEMS(second)-IDELEMS(temp));
+  IDELEMS(temp) = j+IDELEMS(second);
+  for (i=0;i<IDELEMS(second);i++)
+  {
+    if (second->m[i]!=NULL)
+    {
+      if (syz_ring==orig_ring)
+        temp->m[k] = pCopy(second->m[i]);
+      else
+        temp->m[k] = prCopyR(second->m[i], orig_ring);
+      if (slength==0) pShift(&(temp->m[k]),1);
+      k++;
+    }
+  }
+  temp1 = kStd(temp,currQuotient,testHomog,&w,NULL,length);
+  if (w!=NULL) delete w;
+  idDelete(&temp);
+
+  if(syz_ring!=orig_ring)
+    rChangeCurrRing(orig_ring);
+
+  result = idInit(IDELEMS(temp1),rank);
+  j = 0;
+  for (i=0;i<IDELEMS(temp1);i++)
+  {
+    if ((temp1->m[i]!=NULL)
+    && (p_GetComp(temp1->m[i],syz_ring)>length))
+    {
+      if(syz_ring==orig_ring)
+        p = pCopy(temp1->m[i]);
+      else
+        p = prCopyR(temp1->m[i], syz_ring);
+      while (p!=NULL)
+      {
+        q = pNext(p);
+        pNext(p) = NULL;
+        k = pGetComp(p)-1-length;
+        pSetComp(p,0);
+        pSetmComp(p);
+        result->m[j] = pAdd(result->m[j],pMult(pCopy(first->m[k]),p));
+        p = q;
+      }
+      j++;
+    }
+  }
+  if(syz_ring!=orig_ring)
+  {
+    rChangeCurrRing(syz_ring);
+    idDelete(&temp1);
+    rChangeCurrRing(orig_ring);
+    rKill(syz_ring);
+  }
+  else
+  {
+    idDelete(&temp1);
+  }
+
+  idSkipZeroes(result);
+  return result;
+}
+
+/*2
+* ideal/module intersection for a list of objects
+* given as 'resolvente'
+*/
+ideal idMultSect(resolvente arg, int length)
+{
+  int i,j=0,k=0,syzComp,l,maxrk=-1,realrki;
+  ideal bigmat,tempstd,result;
+  poly p;
+  int isIdeal=0;
+  intvec * w=NULL;
+
+  /* find 0-ideals and max rank -----------------------------------*/
+  for (i=0;i<length;i++)
+  {
+    if (!idIs0(arg[i]))
+    {
+      realrki=idRankFreeModule(arg[i]);
+      k++;
+      j += IDELEMS(arg[i]);
+      if (realrki>maxrk) maxrk = realrki;
+    }
+    else
+    {
+      if (arg[i]!=NULL)
+      {
+        return idInit(1,arg[i]->rank);
+      }
+    }
+  }
+  if (maxrk == 0)
+  {
+    isIdeal = 1;
+    maxrk = 1;
+  }
+  /* init -----------------------------------------------------------*/
+  j += maxrk;
+  syzComp = k*maxrk;
+
+  ring orig_ring=currRing;
+  ring syz_ring=rCurrRingAssure_SyzComp();
+  rSetSyzComp(syzComp);
+
+  bigmat = idInit(j,(k+1)*maxrk);
+  /* create unit matrices ------------------------------------------*/
+  for (i=0;i<maxrk;i++)
+  {
+    for (j=0;j<=k;j++)
+    {
+      p = pOne();
+      pSetComp(p,i+1+j*maxrk);
+      pSetmComp(p);
+      bigmat->m[i] = pAdd(bigmat->m[i],p);
+    }
+  }
+  /* enter given ideals ------------------------------------------*/
+  i = maxrk;
+  k = 0;
+  for (j=0;j<length;j++)
+  {
+    if (arg[j]!=NULL)
+    {
+      for (l=0;l<IDELEMS(arg[j]);l++)
+      {
+        if (arg[j]->m[l]!=NULL)
+        {
+          if (syz_ring==orig_ring)
+            bigmat->m[i] = pCopy(arg[j]->m[l]);
+          else
+            bigmat->m[i] = prCopyR(arg[j]->m[l], orig_ring);
+          pShift(&(bigmat->m[i]),k*maxrk+isIdeal);
+          i++;
+        }
+      }
+      k++;
+    }
+  }
+  /* std computation --------------------------------------------*/
+  tempstd = kStd(bigmat,currQuotient,testHomog,&w,NULL,syzComp);
+  if (w!=NULL) delete w;
+  idDelete(&bigmat);
+
+  if(syz_ring!=orig_ring)
+    rChangeCurrRing(orig_ring);
+
+  /* interprete result ----------------------------------------*/
+  result = idInit(8,maxrk);
+  k = 0;
+  for (j=0;j<IDELEMS(tempstd);j++)
+  {
+    if ((tempstd->m[j]!=NULL) && (p_GetComp(tempstd->m[j],syz_ring)>syzComp))
+    {
+      if (k>=IDELEMS(result))
+      {
+        pEnlargeSet(&(result->m),IDELEMS(result),8);
+        IDELEMS(result) += 8;
+      }
+      if (syz_ring==orig_ring)
+        p = pCopy(tempstd->m[j]);
+      else
+        p = prCopyR(tempstd->m[j], syz_ring);
+      pShift(&p,-syzComp-isIdeal);
+      result->m[k] = p;
+      k++;
+    }
+  }
+  /* clean up ----------------------------------------------------*/
+  if(syz_ring!=orig_ring)
+    rChangeCurrRing(syz_ring);
+  idDelete(&tempstd);
+  if(syz_ring!=orig_ring)
+  {
+    rChangeCurrRing(orig_ring);
+    rKill(syz_ring);
+  }
+  idSkipZeroes(result);
+  return result;
+}
+
+/*2
+*computes syzygies of h1,
+*if quot != NULL it computes in the quotient ring modulo "quot"
+*works always in a ring with ringorder_s
+*/
+static ideal idPrepare (ideal  h1, tHomog h, int syzcomp, intvec **w)
+{
+  ideal   h2, h3;
+  int     i;
+  int     j,jj=0,k;
+  poly    p,q;
+
+  if (idIs0(h1)) return NULL;
+  k = idRankFreeModule(h1);
+  h2=idCopy(h1);
+  i = IDELEMS(h2)-1;
+  if (k == 0)
+  {
+    for (j=0; j<=i; j++) pShift(&(h2->m[j]),1);
+    k = 1;
+  }
+  if (syzcomp<k)
+  {
+    Warn("syzcomp too low, should be %d instead of %d",k,syzcomp);
+    syzcomp = k;
+    rSetSyzComp(k);
+  }
+  h2->rank = syzcomp+i+1;
+  for (j=0; j<=i; j++)
+  {
+    p = h2->m[j];
+    q = pOne();
+    pSetComp(q,syzcomp+1+j);
+    pSetmComp(q);
+    if (p!=NULL)
+    {
+      while (pNext(p)) pIter(p);
+      p->next = q;
+    }
+    else
+      h2->m[j]=q;
+  }
+
+#ifdef PDEBUG
+  for(j=0;j<IDELEMS(h2);j++) pTest(h2->m[j]);
+#endif
+  h3=kStd(h2,currQuotient,h,w,NULL,syzcomp);
+  idDelete(&h2);
+  return h3;
+}
+
+/*2
+* compute the syzygies of h1 in R/quot,
+* weights of components are in w
+* if setRegularity, return the regularity in deg
+* do not change h1,  w
+*/
+ideal idSyzygies (ideal  h1, tHomog h,intvec **w, BOOLEAN setSyzComp,
+                  BOOLEAN setRegularity, int *deg)
+{
+  ideal s_h1;
+  poly  p;
+  int   i, j, k, length=0,reg;
+  BOOLEAN isMonomial=TRUE;
+  int ii;
+
+#ifdef PDEBUG
+  for(ii=0;ii<IDELEMS(h1);ii++) pTest(h1->m[ii]);
+#endif
+  if (idIs0(h1))
+  {
+    ideal result=idFreeModule(IDELEMS(h1));
+    int curr_syz_limit=rGetCurrSyzLimit();
+    if (curr_syz_limit>0)
+    for (ii=0;ii<IDELEMS(h1);ii++)
+    {
+      if (h1->m[ii]!=NULL)
+        pShift(&h1->m[ii],curr_syz_limit);
+    }
+    return result;
+  }
+  k=si_max(1,idRankFreeModule(h1));
+
+  assume(currRing != NULL);
+  ring orig_ring=currRing;
+  ring syz_ring=rCurrRingAssure_SyzComp();
+
+  if (setSyzComp)
+    rSetSyzComp(k);
+
+  if (orig_ring != syz_ring)
+  {
+    s_h1=idrCopyR_NoSort(h1,orig_ring);
+  }
+  else
+  {
+    s_h1 = h1;
+  }
+
+  ideal s_h3=idPrepare(s_h1,h,k,w);
+
+  if (s_h3==NULL)
+  {
+    return idFreeModule(IDELEMS(h1));
+  }
+
+  if (orig_ring != syz_ring)
+  {
+    idDelete(&s_h1);
+    for (j=0; j<IDELEMS(s_h3); j++)
+    {
+      if (s_h3->m[j] != NULL)
+      {
+        if (p_MinComp(s_h3->m[j],syz_ring) > k)
+          pShift(&s_h3->m[j], -k);
+        else
+          pDelete(&s_h3->m[j]);
+      }
+    }
+    idSkipZeroes(s_h3);
+    s_h3->rank -= k;
+    rChangeCurrRing(orig_ring);
+    s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
+    rKill(syz_ring);
+    idTest(s_h3);
+    return s_h3;
+  }
+
+  ideal e = idInit(IDELEMS(s_h3), s_h3->rank);
+
+  for (j=0; j<IDELEMS(s_h3); j++)
+  {
+    if (s_h3->m[j] != NULL)
+    {
+      if (p_MinComp(s_h3->m[j],syz_ring) <= k)
+      {
+        e->m[j] = s_h3->m[j];
+        isMonomial=isMonomial && (pNext(s_h3->m[j])==NULL);
+        pDelete(&pNext(s_h3->m[j]));
+        s_h3->m[j] = NULL;
+      }
+    }
+  }
+
+  idSkipZeroes(s_h3);
+  idSkipZeroes(e);
+
+  if ((deg != NULL)
+  && (!isMonomial)
+  && (!TEST_OPT_NOTREGULARITY)
+  && (setRegularity)
+  && (h==isHomog)
+  && (!rIsPluralRing(currRing))
+  )
+  {
+    ring dp_C_ring = rCurrRingAssure_dp_C();
+    if (dp_C_ring != syz_ring)
+      e = idrMoveR_NoSort(e, syz_ring);
+    resolvente res = sySchreyerResolvente(e,-1,&length,TRUE, TRUE);
+    intvec * dummy = syBetti(res,length,&reg, *w);
+    *deg = reg+2;
+    delete dummy;
+    for (j=0;j<length;j++)
+    {
+      if (res[j]!=NULL) idDelete(&(res[j]));
+    }
+    omFreeSize((ADDRESS)res,length*sizeof(ideal));
+    idDelete(&e);
+    if (dp_C_ring != syz_ring)
+    {
+      rChangeCurrRing(syz_ring);
+      rKill(dp_C_ring);
+    }
+  }
+  else
+  {
+    idDelete(&e);
+  }
+  idTest(s_h3);
+  if (currQuotient != NULL)
+  {
+    ideal ts_h3=kStd(s_h3,currQuotient,h,w);
+    idDelete(&s_h3);
+    s_h3 = ts_h3;
+  }
+  return s_h3;
+}
+
+/*2
+*/
+ideal idXXX (ideal  h1, int k)
+{
+  ideal s_h1;
+  int j;
+  intvec *w=NULL;
+
+  assume(currRing != NULL);
+  ring orig_ring=currRing;
+  ring syz_ring=rCurrRingAssure_SyzComp();
+
+  rSetSyzComp(k);
+
+  if (orig_ring != syz_ring)
+  {
+    s_h1=idrCopyR_NoSort(h1,orig_ring);
+  }
+  else
+  {
+    s_h1 = h1;
+  }
+
+  ideal s_h3=kStd(s_h1,NULL,testHomog,&w,NULL,k);
+
+  if (s_h3==NULL)
+  {
+    return idFreeModule(IDELEMS(h1));
+  }
+
+  if (orig_ring != syz_ring)
+  {
+    idDelete(&s_h1);
+    idSkipZeroes(s_h3);
+    rChangeCurrRing(orig_ring);
+    s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
+    rKill(syz_ring);
+    idTest(s_h3);
+    return s_h3;
+  }
+
+  idSkipZeroes(s_h3);
+  idTest(s_h3);
+  return s_h3;
+}
+
+/*
+*computes a standard basis for h1 and stores the transformation matrix
+* in ma
+*/
+ideal idLiftStd (ideal  h1, matrix* ma, tHomog h)
+{
+  int   i, j, k, t, inputIsIdeal=idRankFreeModule(h1);
+  poly  p=NULL, q, qq;
+  intvec *w=NULL;
+
+  idDelete((ideal*)ma);
+  *ma=mpNew(1,0);
+  if (idIs0(h1))
+    return idInit(1,h1->rank);
+  k=si_max(1,idRankFreeModule(h1));
+
+  ring orig_ring=currRing;
+  ring syz_ring=rCurrRingAssure_SyzComp();
+  rSetSyzComp(k);
+
+  ideal s_h1=h1;
+
+  if (orig_ring != syz_ring)
+    s_h1 = idrCopyR_NoSort(h1,orig_ring);
+  else
+    s_h1 = h1;
+
+  ideal s_h3=idPrepare(s_h1,h,k,&w);
+  ideal s_h2 = idInit(IDELEMS(s_h3), s_h3->rank);
+
+  if (w!=NULL) delete w;
+  i = 0;
+  for (j=0; j<IDELEMS(s_h3); j++)
+  {
+    if ((s_h3->m[j] != NULL) && (p_MinComp(s_h3->m[j],syz_ring) <= k))
+    {
+      i++;
+      q = s_h3->m[j];
+      while (pNext(q) != NULL)
+      {
+        if (pGetComp(pNext(q)) > k)
+        {
+          s_h2->m[j] = pNext(q);
+          pNext(q) = NULL;
+        }
+        else
+        {
+          pIter(q);
+        }
+      }
+      if (!inputIsIdeal) pShift(&(s_h3->m[j]), -1);
+    }
+    else
+    {
+      pDelete(&(s_h3->m[j]));
+    }
+  }
+
+  idSkipZeroes(s_h3);
+  j = IDELEMS(s_h1);
+
+  if (syz_ring!=orig_ring)
+  {
+    idDelete(&s_h1);
+    rChangeCurrRing(orig_ring);
+  }
+
+  idDelete((ideal*)ma);
+  *ma = mpNew(j,i);
+
+  i = 1;
+  for (j=0; j<IDELEMS(s_h2); j++)
+  {
+    if (s_h2->m[j] != NULL)
+    {
+      q = prMoveR( s_h2->m[j], syz_ring);
+      s_h2->m[j] = NULL;
+
+      while (q != NULL)
+      {
+        p = q;
+        pIter(q);
+        pNext(p) = NULL;
+        t=pGetComp(p);
+        pSetComp(p,0);
+        pSetmComp(p);
+        MATELEM(*ma,t-k,i) = pAdd(MATELEM(*ma,t-k,i),p);
+      }
+      i++;
+    }
+  }
+  idDelete(&s_h2);
+
+  for (i=0; i<IDELEMS(s_h3); i++)
+  {
+    s_h3->m[i] = prMoveR_NoSort(s_h3->m[i], syz_ring);
+  }
+
+  if (syz_ring!=orig_ring) rKill(syz_ring);
+  return s_h3;
+}
+
+static void idPrepareStd(ideal s_temp, int k)
+{
+  int j,rk=idRankFreeModule(s_temp);
+  poly p,q;
+
+  if (rk == 0)
+  {
+    for (j=0; j<IDELEMS(s_temp); j++)
+    {
+      if (s_temp->m[j]!=NULL) pSetCompP(s_temp->m[j],1);
+    }
+    k = si_max(k,1);
+  }
+  for (j=0; j<IDELEMS(s_temp); j++)
+  {
+    if (s_temp->m[j]!=NULL)
+    {
+      p = s_temp->m[j];
+      q = pOne();
+      //pGetCoeff(q)=nNeg(pGetCoeff(q));   //set q to -1
+      pSetComp(q,k+1+j);
+      pSetmComp(q);
+      while (pNext(p)) pIter(p);
+      pNext(p) = q;
+    }
+  }
+}
+
+/*2
+*computes a representation of the generators of submod with respect to those
+* of mod
+*/
+
+ideal idLift(ideal mod, ideal submod,ideal *rest, BOOLEAN goodShape,
+             BOOLEAN isSB, BOOLEAN divide, matrix *unit)
+{
+  int lsmod =idRankFreeModule(submod), i, j, k;
+  int comps_to_add=0;
+  poly p;
+
+  if (idIs0(submod))
+  {
+    if (unit!=NULL)
+    {
+      *unit=mpNew(1,1);
+      MATELEM(*unit,1,1)=pOne();
+    }
+    if (rest!=NULL)
+    {
+      *rest=idInit(1,mod->rank);
+    }
+    return idInit(1,mod->rank);
+  }
+  if (idIs0(mod))
+  {
+    if (unit!=NULL)
+    {
+      i=IDELEMS(submod);
+      *unit=mpNew(i,i);
+      for (j=i;j>0;j--)
+      {
+        MATELEM(*unit,j,j)=pOne();
+      }
+    }
+    if (rest!=NULL)
+    {
+      *rest=idCopy(submod);
+    }
+    return idInit(1,mod->rank);
+  }
+  if (unit!=NULL)
+  {
+    comps_to_add = IDELEMS(submod);
+    while ((comps_to_add>0) && (submod->m[comps_to_add-1]==NULL))
+      comps_to_add--;
+  }
+  k=idRankFreeModule(mod);
+  if  ((k!=0) && (lsmod==0)) lsmod=1;
+  k=si_max(k,1);
+
+  ring orig_ring=currRing;
+  ring syz_ring=rCurrRingAssure_SyzComp();
+  rSetSyzComp(k);
+
+  ideal s_mod, s_temp;
+  if (orig_ring != syz_ring)
+  {
+    s_mod = idrCopyR_NoSort(mod,orig_ring);
+    s_temp = idrCopyR_NoSort(submod,orig_ring);
+  }
+  else
+  {
+    s_mod = mod;
+    s_temp = idCopy(submod);
+  }
+  ideal s_h3;
+  if (isSB)
+  {
+    s_h3 = idCopy(s_mod);
+    idPrepareStd(s_h3, k+comps_to_add);
+  }
+  else
+  {
+    s_h3 = idPrepare(s_mod,(tHomog)FALSE,k+comps_to_add,NULL);
+  }
+  if (!goodShape)
+  {
+    for (j=0;j<IDELEMS(s_h3);j++)
+    {
+      if ((s_h3->m[j] != NULL) && (pMinComp(s_h3->m[j]) > k))
+        pDelete(&(s_h3->m[j]));
+    }
+  }
+  idSkipZeroes(s_h3);
+  if (lsmod==0)
+  {
+    for (j=IDELEMS(s_temp);j>0;j--)
+    {
+      if (s_temp->m[j-1]!=NULL)
+        pShift(&(s_temp->m[j-1]),1);
+    }
+  }
+  if (unit!=NULL)
+  {
+    for(j = 0;j<comps_to_add;j++)
+    {
+      p = s_temp->m[j];
+      if (p!=NULL)
+      {
+        while (pNext(p)!=NULL) pIter(p);
+        pNext(p) = pOne();
+        pIter(p);
+        pSetComp(p,1+j+k);
+        pSetmComp(p);
+        p = pNeg(p);
+      }
+    }
+  }
+  ideal s_result = kNF(s_h3,currQuotient,s_temp,k);
+  s_result->rank = s_h3->rank;
+  ideal s_rest = idInit(IDELEMS(s_result),k);
+  idDelete(&s_h3);
+  idDelete(&s_temp);
+
+  for (j=0;j<IDELEMS(s_result);j++)
+  {
+    if (s_result->m[j]!=NULL)
+    {
+      if (pGetComp(s_result->m[j])<=k)
+      {
+        if (!divide)
+        {
+          if (isSB)
+          {
+            WarnS("first module not a standardbasis\n"
+              "// ** or second not a proper submodule");
+          }
+          else
+            WerrorS("2nd module lies not in the first");
+          idDelete(&s_result);
+          idDelete(&s_rest);
+          s_result=idInit(IDELEMS(submod),submod->rank);
+          break;
+        }
+        else
+        {
+          p = s_rest->m[j] = s_result->m[j];
+          while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=k)) pIter(p);
+          s_result->m[j] = pNext(p);
+          pNext(p) = NULL;
+        }
+      }
+      pShift(&(s_result->m[j]),-k);
+      pNeg(s_result->m[j]);
+    }
+  }
+  if ((lsmod==0) && (!idIs0(s_rest)))
+  {
+    for (j=IDELEMS(s_rest);j>0;j--)
+    {
+      if (s_rest->m[j-1]!=NULL)
+      {
+        pShift(&(s_rest->m[j-1]),-1);
+        s_rest->m[j-1] = s_rest->m[j-1];
+      }
+    }
+  }
+  if(syz_ring!=orig_ring)
+  {
+    idDelete(&s_mod);
+    rChangeCurrRing(orig_ring);
+    s_result = idrMoveR_NoSort(s_result, syz_ring);
+    s_rest = idrMoveR_NoSort(s_rest, syz_ring);
+    rKill(syz_ring);
+  }
+  if (rest!=NULL)
+    *rest = s_rest;
+  else
+    idDelete(&s_rest);
+//idPrint(s_result);
+  if (unit!=NULL)
+  {
+    *unit=mpNew(comps_to_add,comps_to_add);
+    int i;
+    for(i=0;i<IDELEMS(s_result);i++)
+    {
+      poly p=s_result->m[i];
+      poly q=NULL;
+      while(p!=NULL)
+      {
+        if(pGetComp(p)<=comps_to_add)
+        {
+          pSetComp(p,0);
+          if (q!=NULL)
+          {
+            pNext(q)=pNext(p);
+          }
+          else
+          {
+            pIter(s_result->m[i]);
+          }
+          pNext(p)=NULL;
+          MATELEM(*unit,i+1,i+1)=pAdd(MATELEM(*unit,i+1,i+1),p);
+          if(q!=NULL)   p=pNext(q);
+          else          p=s_result->m[i];
+        }
+        else
+        {
+          q=p;
+          pIter(p);
+        }
+      }
+      pShift(&s_result->m[i],-comps_to_add);
+    }
+  }
+  return s_result;
+}
+
+/*2
+*computes division of P by Q with remainder up to (w-weighted) degree n
+*P, Q, and w are not changed
+*/
+void idLiftW(ideal P,ideal Q,int n,matrix &T, ideal &R,short *w)
+{
+  int N=0;
+  int i;
+  for(i=IDELEMS(Q)-1;i>=0;i--)
+    if(w==NULL)
+      N=si_max(N,pDeg(Q->m[i]));
+    else
+      N=si_max(N,pDegW(Q->m[i],w));
+  N+=n;
+
+  T=mpNew(IDELEMS(Q),IDELEMS(P));
+  R=idInit(IDELEMS(P),P->rank);
+
+  for(i=IDELEMS(P)-1;i>=0;i--)
+  {
+    poly p;
+    if(w==NULL)
+      p=ppJet(P->m[i],N);
+    else
+      p=ppJetW(P->m[i],N,w);
+
+    int j=IDELEMS(Q)-1;
+    while(p!=NULL)
+    {
+      if(pDivisibleBy(Q->m[j],p))
+      {
+        poly p0=pDivideM(pHead(p),pHead(Q->m[j]));
+        if(w==NULL)
+          p=pJet(pSub(p,ppMult_mm(Q->m[j],p0)),N);
+        else
+          p=pJetW(pSub(p,ppMult_mm(Q->m[j],p0)),N,w);
+        pNormalize(p);
+        if(w==NULL&&pDeg(p0)>n||w!=NULL&&pDegW(p0,w)>n)
+          pDelete(&p0);
+        else
+          MATELEM(T,j+1,i+1)=pAdd(MATELEM(T,j+1,i+1),p0);
+        j=IDELEMS(Q)-1;
+      }
+      else
+      {
+        if(j==0)
+        {
+          poly p0=p;
+          pIter(p);
+          pNext(p0)=NULL;
+          if(w==NULL&&pDeg(p0)>n||w!=NULL&&pDegW(p0,w)>n)
+            pDelete(&p0);
+          else
+            R->m[i]=pAdd(R->m[i],p0);
+          j=IDELEMS(Q)-1;
+        }
+        else
+          j--;
+      }
+    }
+  }
+}
+
+/*2
+*computes the quotient of h1,h2 : interanl routine for idQuot
+*BEWARE: the returned ideals may contain incorrected orderd polys !
+*
+*/
+static ideal idInitializeQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb,
+                               BOOLEAN *addOnlyOne, int *kkmax)
+{
+  ideal temph1;
+  poly     p,q = NULL;
+  int i,l,ll,k,kkk,kmax;
+  int j = 0;
+  int k1 = idRankFreeModule(h1);
+  int k2 = idRankFreeModule(h2);
+  tHomog   hom=isNotHomog;
+
+  k=si_max(k1,k2);
+  if (k==0)
+    k = 1;
+  if ((k2==0) && (k>1)) *addOnlyOne = FALSE;
+
+  intvec * weights;
+  hom = (tHomog)idHomModule(h1,currQuotient,&weights);
+  if (addOnlyOne && (!h1IsStb))
+    temph1 = kStd(h1,currQuotient,hom,&weights,NULL);
+  else
+    temph1 = idCopy(h1);
+  if (weights!=NULL) delete weights;
+  idTest(temph1);
+/*--- making a single vector from h2 ---------------------*/
+  for (i=0; i<IDELEMS(h2); i++)
+  {
+    if (h2->m[i] != NULL)
+    {
+      p = pCopy(h2->m[i]);
+      if (k2 == 0)
+        pShift(&p,j*k+1);
+      else
+        pShift(&p,j*k);
+      q = pAdd(q,p);
+      j++;
+    }
+  }
+  *kkmax = kmax = j*k+1;
+/*--- adding a monomial for the result (syzygy) ----------*/
+  p = q;
+  while (pNext(p)!=NULL) pIter(p);
+  pNext(p) = pOne();
+  pIter(p);
+  pSetComp(p,kmax);
+  pSetmComp(p);
+/*--- constructing the big matrix ------------------------*/
+  ideal h4 = idInit(16,kmax+k-1);
+  h4->m[0] = q;
+  if (k2 == 0)
+  {
+    if (k > IDELEMS(h4))
+    {
+      pEnlargeSet(&(h4->m),IDELEMS(h4),k-IDELEMS(h4));
+      IDELEMS(h4) = k;
+    }
+    for (i=1; i<k; i++)
+    {
+      p = pCopy_noCheck(h4->m[i-1]);
+      pShift(&p,1);
+      h4->m[i] = p;
+    }
+  }
+
+  kkk = IDELEMS(h4);
+  i = IDELEMS(temph1);
+  while ((i>0) && (temph1->m[i-1]==NULL)) i--;
+  for (l=0; l<i; l++)
+  {
+    if(temph1->m[l]!=NULL)
+    {
+      for (ll=0; ll<j; ll++)
+      {
+        p = pCopy(temph1->m[l]);
+        if (k1 == 0)
+          pShift(&p,ll*k+1);
+        else
+          pShift(&p,ll*k);
+        if (kkk >= IDELEMS(h4))
+        {
+          pEnlargeSet(&(h4->m),IDELEMS(h4),16);
+          IDELEMS(h4) += 16;
+        }
+        h4->m[kkk] = p;
+        kkk++;
+      }
+    }
+  }
+/*--- if h2 goes in as single vector - the h1-part is just SB ---*/
+  if (*addOnlyOne)
+  {
+    p = h4->m[0];
+    for (i=0;i<IDELEMS(h4)-1;i++)
+    {
+      h4->m[i] = h4->m[i+1];
+    }
+    h4->m[IDELEMS(h4)-1] = p;
+    idSkipZeroes(h4);
+    test |= Sy_bit(OPT_SB_1);
+  }
+  idDelete(&temph1);
+  return h4;
+}
+/*2
+*computes the quotient of h1,h2
+*/
+ideal idQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb, BOOLEAN resultIsIdeal)
+{
+  // first check for special case h1:(0)
+  if (idIs0(h2))
+  {
+    ideal res;
+    if (resultIsIdeal)
+    {
+      res = idInit(1,1);
+      res->m[0] = pOne();
+    }
+    else
+      res = idFreeModule(h1->rank);
+    return res;
+  }
+  BITSET old_test=test;
+  poly     p,q = NULL;
+  int i,l,ll,k,kkk,kmax;
+  BOOLEAN  addOnlyOne=TRUE;
+  tHomog   hom=isNotHomog;
+  intvec * weights1;
+
+  ideal s_h4 = idInitializeQuot (h1,h2,h1IsStb,&addOnlyOne,&kmax);
+
+  hom = (tHomog)idHomModule(s_h4,currQuotient,&weights1);
+
+  ring orig_ring=currRing;
+  ring syz_ring=rCurrRingAssure_SyzComp();
+  rSetSyzComp(kmax-1);
+  if (orig_ring!=syz_ring)
+  //  s_h4 = idrMoveR_NoSort(s_h4,orig_ring);
+    s_h4 = idrMoveR(s_h4,orig_ring);
+  idTest(s_h4);
+  ideal s_h3;
+  if (addOnlyOne)
+  {
+    s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,kmax-1,IDELEMS(s_h4)-1);
+  }
+  else
+  {
+    s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,kmax-1);
+  }
+  idTest(s_h3);
+  if (weights1!=NULL) delete weights1;
+  idDelete(&s_h4);
+
+
+  for (i=0;i<IDELEMS(s_h3);i++)
+  {
+    if ((s_h3->m[i]!=NULL) && (pGetComp(s_h3->m[i])>=kmax))
+    {
+      if (resultIsIdeal)
+        pShift(&s_h3->m[i],-kmax);
+      else
+        pShift(&s_h3->m[i],-kmax+1);
+    }
+    else
+      pDelete(&s_h3->m[i]);
+  }
+  if (resultIsIdeal)
+    s_h3->rank = 1;
+  else
+    s_h3->rank = h1->rank;
+  if(syz_ring!=orig_ring)
+  {
+//    pDelete(&q);
+    rChangeCurrRing(orig_ring);
+    s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
+    rKill(syz_ring);
+  }
+  idSkipZeroes(s_h3);
+  test = old_test;
+  idTest(s_h3);
+  return s_h3;
+}
+
+/*2
+*computes recursively all monomials of a certain degree
+*in every step the actvar-th entry in the exponential
+*vector is incremented and the other variables are
+*computed by recursive calls of makemonoms
+*if the last variable is reached, the difference to the
+*degree is computed directly
+*vars is the number variables
+*actvar is the actual variable to handle
+*deg is the degree of the monomials to compute
+*monomdeg is the actual degree of the monomial in consideration
+*/
+static void makemonoms(int vars,int actvar,int deg,int monomdeg)
+{
+  poly p;
+  int i=0;
+
+  if ((idpowerpoint == 0) && (actvar ==1))
+  {
+    idpower[idpowerpoint] = pOne();
+    monomdeg = 0;
+  }
+  while (i<=deg)
+  {
+    if (deg == monomdeg)
+    {
+      pSetm(idpower[idpowerpoint]);
+      idpowerpoint++;
+      return;
+    }
+    if (actvar == vars)
+    {
+      pSetExp(idpower[idpowerpoint],actvar,deg-monomdeg);
+      pSetm(idpower[idpowerpoint]);
+      pTest(idpower[idpowerpoint]);
+      idpowerpoint++;
+      return;
+    }
+    else
+    {
+      p = pCopy(idpower[idpowerpoint]);
+      makemonoms(vars,actvar+1,deg,monomdeg);
+      idpower[idpowerpoint] = p;
+    }
+    monomdeg++;
+    pSetExp(idpower[idpowerpoint],actvar,pGetExp(idpower[idpowerpoint],actvar)+1);
+    pSetm(idpower[idpowerpoint]);
+    pTest(idpower[idpowerpoint]);
+    i++;
+  }
+}
+
+/*2
+*returns the deg-th power of the maximal ideal of 0
+*/
+ideal idMaxIdeal(int deg)
+{
+  if (deg < 0)
+  {
+    WarnS("maxideal: power must be non-negative");
+  }
+  if (deg < 1)
+  {
+    ideal I=idInit(1,1);
+    I->m[0]=pOne();
+    return I;
+  }
+  if (deg == 1)
+  {
+    return idMaxIdeal();
+  }
+
+  int vars = currRing->N;
+  int i = binom(vars+deg-1,deg);
+  if (i<=0) return idInit(1,1);
+  ideal id=idInit(i,1);
+  idpower = id->m;
+  idpowerpoint = 0;
+  makemonoms(vars,1,deg,0);
+  idpower = NULL;
+  idpowerpoint = 0;
+  return id;
+}
+
+/*2
+*computes recursively all generators of a certain degree
+*of the ideal "givenideal"
+*elms is the number elements in the given ideal
+*actelm is the actual element to handle
+*deg is the degree of the power to compute
+*gendeg is the actual degree of the generator in consideration
+*/
+static void makepotence(int elms,int actelm,int deg,int gendeg)
+{
+  poly p;
+  int i=0;
+
+  if ((idpowerpoint == 0) && (actelm ==1))
+  {
+    idpower[idpowerpoint] = pOne();
+    gendeg = 0;
+  }
+  while (i<=deg)
+  {
+    if (deg == gendeg)
+    {
+      idpowerpoint++;
+      return;
+    }
+    if (actelm == elms)
+    {
+      p=pPower(pCopy(givenideal[actelm-1]),deg-gendeg);
+      idpower[idpowerpoint]=pMult(idpower[idpowerpoint],p);
+      idpowerpoint++;
+      return;
+    }
+    else
+    {
+      p = pCopy(idpower[idpowerpoint]);
+      makepotence(elms,actelm+1,deg,gendeg);
+      idpower[idpowerpoint] = p;
+    }
+    gendeg++;
+    idpower[idpowerpoint]=pMult(idpower[idpowerpoint],pCopy(givenideal[actelm-1]));
+    i++;
+  }
+}
+
+/*2
+*returns the deg-th power of the ideal gid
+*/
+//ideal idPower(ideal gid,int deg)
+//{
+//  int i;
+//  ideal id;
+//
+//  if (deg < 1) deg = 1;
+//  i = binom(IDELEMS(gid)+deg-1,deg);
+//  id=idInit(i,1);
+//  idpower = id->m;
+//  givenideal = gid->m;
+//  idpowerpoint = 0;
+//  makepotence(IDELEMS(gid),1,deg,0);
+//  idpower = NULL;
+//  givenideal = NULL;
+//  idpowerpoint = 0;
+//  return id;
+//}
+static void idNextPotence(ideal given, ideal result,
+  int begin, int end, int deg, int restdeg, poly ap)
+{
+  poly p;
+  int i;
+
+  p = pPower(pCopy(given->m[begin]),restdeg);
+  i = result->nrows;
+  result->m[i] = pMult(pCopy(ap),p);
+//PrintS(".");
+  (result->nrows)++;
+  if (result->nrows >= IDELEMS(result))
+  {
+    pEnlargeSet(&(result->m),IDELEMS(result),16);
+    IDELEMS(result) += 16;
+  }
+  if (begin == end) return;
+  for (i=restdeg-1;i>0;i--)
+  {
+    p = pPower(pCopy(given->m[begin]),i);
+    p = pMult(pCopy(ap),p);
+    idNextPotence(given, result, begin+1, end, deg, restdeg-i, p);
+    pDelete(&p);
+  }
+  idNextPotence(given, result, begin+1, end, deg, restdeg, ap);
+}
+
+ideal idPower(ideal given,int exp)
+{
+  ideal result,temp;
+  poly p1;
+  int i;
+
+  if (idIs0(given)) return idInit(1,1);
+  temp = idCopy(given);
+  idSkipZeroes(temp);
+  i = binom(IDELEMS(temp)+exp-1,exp);
+  result = idInit(i,1);
+  result->nrows = 0;
+//Print("ideal contains %d elements\n",i);
+  p1=pOne();
+  idNextPotence(temp,result,0,IDELEMS(temp)-1,exp,exp,p1);
+  pDelete(&p1);
+  idDelete(&temp);
+  result->nrows = 1;
+  idSkipZeroes(result);
+  idDelEquals(result);
+  return result;
+}
+
+/*2
+* eliminate delVar (product of vars) in h1
+*/
+ideal idElimination (ideal h1,poly delVar,intvec *hilb)
+{
+  int    i,j=0,k,l;
+  ideal  h,hh, h3;
+  int    *ord,*block0,*block1;
+  int    ordersize=2;
+  int    **wv;
+  tHomog hom;
+  intvec * w;
+  sip_sring tmpR;
+  ring origR = currRing;
+
+  if (delVar==NULL)
+  {
+    return idCopy(h1);
+  }
+  if (currQuotient!=NULL)
+  {
+    WerrorS("cannot eliminate in a qring");
+    return idCopy(h1);
+  }
+  if (idIs0(h1)) return idInit(1,h1->rank);
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(currRing))
+    /* in the NC case, we have to check the admissibility of */
+    /* the subalgebra to be intersected with */
+  {
+    if (currRing->nc->type!=nc_skew)
+    {
+      if (!nc_CheckSubalgebra(delVar,currRing))
+      {
+        WerrorS("no elimination is possible: subalgebra is not admissible");
+        return idCopy(h1);
+      }
+    }
+  }
+#endif
+  hom=(tHomog)idHomModule(h1,NULL,&w); //sets w to weight vector or NULL
+  h3=idInit(16,h1->rank);
+  for (k=0;; k++)
+  {
+    if (currRing->order[k]!=0) ordersize++;
+    else break;
+  }
+  ord=(int*)omAlloc0(ordersize*sizeof(int));
+  block0=(int*)omAlloc(ordersize*sizeof(int));
+  block1=(int*)omAlloc(ordersize*sizeof(int));
+  for (k=0;; k++)
+  {
+    if (currRing->order[k]!=0)
+    {
+      block0[k+1] = currRing->block0[k];
+      block1[k+1] = currRing->block1[k];
+      ord[k+1] = currRing->order[k];
+    }
+    else
+      break;
+  }
+  block0[0] = 1;
+  block1[0] = pVariables;
+  wv=(int**) omAlloc0(ordersize*sizeof(int**));
+  memcpy4(wv+1,currRing->wvhdl,(ordersize-1)*sizeof(int**));
+  wv[0]=(int*)omAlloc((pVariables+1)*sizeof(int));
+  memset(wv[0],0,(pVariables+1)*sizeof(int));
+  for (j=0;j<pVariables;j++)
+    if (pGetExp(delVar,j+1)!=0) wv[0][j]=1;
+  // use this special ordering: like ringorder_a, except that pFDeg, pWeights
+  // ignore it
+  ord[0] = ringorder_aa;
+
+  // fill in tmp ring to get back the data later on
+  tmpR  = *origR;
+  tmpR.order = ord;
+  tmpR.block0 = block0;
+  tmpR.block1 = block1;
+  tmpR.wvhdl = wv;
+  rComplete(&tmpR, 1);
+
+  // change into the new ring
+  //pChangeRing(pVariables,currRing->OrdSgn,ord,block0,block1,wv);
+  rChangeCurrRing(&tmpR);
+  h = idInit(IDELEMS(h1),h1->rank);
+  // fetch data from the old ring
+  for (k=0;k<IDELEMS(h1);k++) h->m[k] = prCopyR( h1->m[k], origR);
+  // compute kStd
+  hh = kStd(h,NULL,hom,&w,hilb);
+  idDelete(&h);
+
+  // go back to the original ring
+  rChangeCurrRing(origR);
+  i = IDELEMS(hh)-1;
+  while ((i >= 0) && (hh->m[i] == NULL)) i--;
+  j = -1;
+  // fetch data from temp ring
+  for (k=0; k<=i; k++)
+  {
+    l=pVariables;
+    while ((l>0) && (p_GetExp( hh->m[k],l,&tmpR)*pGetExp(delVar,l)==0)) l--;
+    if (l==0)
+    {
+      j++;
+      if (j >= IDELEMS(h3))
+      {
+        pEnlargeSet(&(h3->m),IDELEMS(h3),16);
+        IDELEMS(h3) += 16;
+      }
+      h3->m[j] = prCopyR( hh->m[k], &tmpR);
+    }
+  }
+  id_Delete(&hh, &tmpR);
+  idSkipZeroes(h3);
+  omFree((ADDRESS)wv[0]);
+  omFreeSize((ADDRESS)wv,ordersize*sizeof(int**));
+  omFreeSize((ADDRESS)ord,ordersize*sizeof(int));
+  omFreeSize((ADDRESS)block0,ordersize*sizeof(int));
+  omFreeSize((ADDRESS)block1,ordersize*sizeof(int));
+  rUnComplete(&tmpR);
+  if (w!=NULL)
+    delete w;
+  return h3;
+}
+
+#ifdef WITH_OLD_MINOR
+/*2
+* compute all ar-minors of the matrix a
+*/
+ideal idMinors(matrix a, int ar, ideal R)
+{
+  int     i,j,k,size;
+  int *rowchoise,*colchoise;
+  BOOLEAN rowch,colch;
+  ideal result;
+  matrix tmp;
+  poly p,q;
+
+  i = binom(a->rows(),ar);
+  j = binom(a->cols(),ar);
+
+  rowchoise=(int *)omAlloc(ar*sizeof(int));
+  colchoise=(int *)omAlloc(ar*sizeof(int));
+  if ((i>512) || (j>512) || (i*j >512)) size=512;
+  else size=i*j;
+  result=idInit(size,1);
+  tmp=mpNew(ar,ar);
+  k = 0; /* the index in result*/
+  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
+  while (!rowch)
+  {
+    idInitChoise(ar,1,a->cols(),&colch,colchoise);
+    while (!colch)
+    {
+      for (i=1; i<=ar; i++)
+      {
+        for (j=1; j<=ar; j++)
+        {
+          MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
+        }
+      }
+      p = mpDetBareiss(tmp);
+      if (p!=NULL)
+      {
+        if (R!=NULL)
+        {
+          q = p;
+          p = kNF(R,currQuotient,q);
+          pDelete(&q);
+        }
+        if (p!=NULL)
+        {
+          if (k>=size)
+          {
+            pEnlargeSet(&result->m,size,32);
+            size += 32;
+          }
+          result->m[k] = p;
+          k++;
+        }
+      }
+      idGetNextChoise(ar,a->cols(),&colch,colchoise);
+    }
+    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
+  }
+  /*delete the matrix tmp*/
+  for (i=1; i<=ar; i++)
+  {
+    for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
+  }
+  idDelete((ideal*)&tmp);
+  if (k==0)
+  {
+    k=1;
+    result->m[0]=NULL;
+  }
+  omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
+  omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
+  pEnlargeSet(&result->m,size,k-size);
+  IDELEMS(result) = k;
+  return (result);
+}
+#else
+/*2
+* compute all ar-minors of the matrix a
+* the caller of mpRecMin
+* the elements of the result are not in R (if R!=NULL)
+*/
+ideal idMinors(matrix a, int ar, ideal R)
+{
+  int elems=0;
+  int r=a->nrows,c=a->ncols;
+  int i;
+  matrix b;
+  ideal result,h;
+  ring origR;
+  sip_sring tmpR;
+  Exponent_t bound;
+
+  if((ar<=0) || (ar>r) || (ar>c))
+  {
+    Werror("%d-th minor, matrix is %dx%d",ar,r,c);
+    return NULL;
+  }
+  h = idMatrix2Module(mpCopy(a));
+  bound = smExpBound(h,c,r,ar);
+  idDelete(&h);
+  smRingChange(&origR,tmpR,bound);
+  b = mpNew(r,c);
+  for (i=r*c-1;i>=0;i--)
+  {
+    if (a->m[i])
+      b->m[i] = prCopyR(a->m[i],origR);
+  }
+  if (R) R = idrCopyR(R,origR);
+  result=idInit(32,1);
+  if(ar>1) mpRecMin(ar-1,result,elems,b,r,c,NULL,R);
+  else mpMinorToResult(result,elems,b,r,c,R);
+  idDelete((ideal *)&b);
+  if (R) idDelete(&R);
+  idSkipZeroes(result);
+  rChangeCurrRing(origR);
+  result = idrMoveR(result,&tmpR);
+  smRingClean(origR,tmpR);
+  idTest(result);
+  return result;
+}
+#endif
+
+/*2
+*skips all zeroes and double elements, searches also for units
+*/
+ideal idCompactify(ideal id)
+{
+  int i,j;
+  BOOLEAN b=FALSE;
+
+  i = IDELEMS(id)-1;
+  while ((! b) && (i>=0))
+  {
+    b=pIsUnit(id->m[i]);
+    i--;
+  }
+  if (b)
+  {
+    ideal result=idInit(1,id->rank);
+    result->m[0]=pOne();
+    return result;
+  }
+  else
+  {
+    ideal result=idCopy(id);
+    //if (IDELEMS(result) < 1)
+    {
+      for (i=1;i<IDELEMS(result);i++)
+      {
+        if (result->m[i]!=NULL)
+        {
+          for (j=0;j<i;j++)
+          {
+            if ((result->m[j]!=NULL)
+            && (pComparePolys(result->m[i],result->m[j])))
+            {
+              pDelete(&(result->m[j]));
+            }
+          }
+        }
+      }
+    }
+//    else
+//    {
+//      intvec *v=idSort(result,TRUE);
+//      for(i=0;i<IDELEMS(result);i++)
+//        (*v)[i]--;
+//      for (i=0;i<IDELEMS(result)-1;i++)
+//      {
+//        if (((*v)[i]>=0)
+//        && (result->m[(*v)[i]]!=NULL))
+//        {
+//          j=i+1;
+//          while ((j<IDELEMS(result))
+//          && ((*v)[j]>=0)
+//          && (result->m[(*v)[j]]!=NULL)
+//          && (pComparePolys(result->m[(*v)[i]],result->m[(*v)[j]])))
+//          {
+//            pDelete(&(result->m[(*v)[j]]));
+//            j++;
+//          }
+//        }
+//      }
+//      delete v;
+//    }
+    idSkipZeroes(result);
+    return result;
+  }
+}
+
+/*2
+*returns TRUE if id1 is a submodule of id2
+*/
+BOOLEAN idIsSubModule(ideal id1,ideal id2)
+{
+  int i;
+  poly p;
+
+  if (idIs0(id1)) return TRUE;
+  for (i=0;i<IDELEMS(id1);i++)
+  {
+    if (id1->m[i] != NULL)
+    {
+      p = kNF(id2,currQuotient,id1->m[i]);
+      if (p != NULL)
+      {
+        pDelete(&p);
+        return FALSE;
+      }
+    }
+  }
+  return TRUE;
+}
+
+/*2
+* returns the ideals of initial terms
+*/
+ideal idHead(ideal h)
+{
+  ideal m = idInit(IDELEMS(h),h->rank);
+  int i;
+
+  for (i=IDELEMS(h)-1;i>=0; i--)
+  {
+    if (h->m[i]!=NULL) m->m[i]=pHead(h->m[i]);
+  }
+  return m;
+}
+
+ideal idHomogen(ideal h, int varnum)
+{
+  ideal m = idInit(IDELEMS(h),h->rank);
+  int i;
+
+  for (i=IDELEMS(h)-1;i>=0; i--)
+  {
+    m->m[i]=pHomogen(h->m[i],varnum);
+  }
+  return m;
+}
+
+/*------------------type conversions----------------*/
+ideal idVec2Ideal(poly vec)
+{
+   ideal result=idInit(1,1);
+   omFree((ADDRESS)result->m);
+   result->m=NULL; // remove later
+   pVec2Polys(vec, &(result->m), &(IDELEMS(result)));
+   return result;
+}
+
+// #define NEW_STUFF
+#ifndef NEW_STUFF
+// converts mat to module, destroys mat
+ideal idMatrix2Module(matrix mat)
+{
+  int mc=MATCOLS(mat);
+  int mr=MATROWS(mat);
+  ideal result = idInit(si_max(mc,1),si_max(mr,1));
+  int i,j;
+  poly h;
+
+  for(j=0;j<mc /*MATCOLS(mat)*/;j++) /* j is also index in result->m */
+  {
+    for (i=1;i<=mr /*MATROWS(mat)*/;i++)
+    {
+      h = MATELEM(mat,i,j+1);
+      if (h!=NULL)
+      {
+        MATELEM(mat,i,j+1)=NULL;
+        pSetCompP(h,i);
+        result->m[j] = pAdd(result->m[j],h);
+      }
+    }
+  }
+  // obachman: need to clean this up
+  idDelete((ideal*) &mat);
+  return result;
+}
+#else
+
+#include "sbuckets.h"
+
+// converts mat to module, destroys mat
+ideal idMatrix2Module(matrix mat)
+{
+  int mc=MATCOLS(mat);
+  int mr=MATROWS(mat);
+  ideal result = idInit(si_max(mc,1),si_max(mr,1));
+  int i,j, l;
+  poly h;
+  poly p;
+  sBucket_pt bucket = sBucketInit(currRing);
+
+  for(j=0;j<mc /*MATCOLS(mat)*/;j++) /* j is also index in result->m */
+  {
+    for (i=1;i<=mr /*MATROWS(mat)*/;i++)
+    {
+      h = MATELEM(mat,i,j+1);
+      if (h!=NULL)
+      {
+        MATELEM(mat,i,j+1)=NULL;
+        p_SetCompP(h,i, currRing, &l);
+        sBucket_Merge_p(bucket, h, l);
+      }
+    }
+    sBucketClearMerge(bucket, &(result->m[j]), &l);
+  }
+
+  // obachman: need to clean this up
+  idDelete((ideal*) &mat);
+  return result;
+}
+#endif
+
+/*2
+* converts a module into a matrix, destroyes the input
+*/
+matrix idModule2Matrix(ideal mod)
+{
+  matrix result = mpNew(mod->rank,IDELEMS(mod));
+  int i,cp;
+  poly p,h;
+
+  for(i=0;i<IDELEMS(mod);i++)
+  {
+    p=mod->m[i];
+    mod->m[i]=NULL;
+    while (p!=NULL)
+    {
+      h=p;
+      pIter(p);
+      pNext(h)=NULL;
+//      cp = si_max(1,pGetComp(h));     // if used for ideals too
+      cp = pGetComp(h);
+      pSetComp(h,0);
+      pSetmComp(h);
+#ifdef TEST
+      if (cp>mod->rank)
+      {
+        Print("## inv. rank %d -> %d\n",mod->rank,cp);
+        int k,l,o=mod->rank;
+        mod->rank=cp;
+        matrix d=mpNew(mod->rank,IDELEMS(mod));
+        for (l=1; l<=o; l++)
+        {
+          for (k=1; k<=IDELEMS(mod); k++)
+          {
+            MATELEM(d,l,k)=MATELEM(result,l,k);
+            MATELEM(result,l,k)=NULL;
+          }
+        }
+        idDelete((ideal *)&result);
+        result=d;
+      }
+#endif
+      MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
+    }
+  }
+  // obachman 10/99: added the following line, otherwise memory leack!
+  idDelete(&mod);
+  return result;
+}
+
+matrix idModule2formatedMatrix(ideal mod,int rows, int cols)
+{
+  matrix result = mpNew(rows,cols);
+  int i,cp,r=idRankFreeModule(mod),c=IDELEMS(mod);
+  poly p,h;
+
+  if (r>rows) r = rows;
+  if (c>cols) c = cols;
+  for(i=0;i<c;i++)
+  {
+    p=mod->m[i];
+    mod->m[i]=NULL;
+    while (p!=NULL)
+    {
+      h=p;
+      pIter(p);
+      pNext(h)=NULL;
+      cp = pGetComp(h);
+      if (cp<=r)
+      {
+        pSetComp(h,0);
+        pSetmComp(h);
+        MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
+      }
+      else
+        pDelete(&h);
+    }
+  }
+  idDelete(&mod);
+  return result;
+}
+
+/*2
+* substitute the n-th variable by the monomial e in id
+* destroy id
+*/
+ideal  idSubst(ideal id, int n, poly e)
+{
+  int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
+  ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
+
+  res->rank = id->rank;
+  for(k--;k>=0;k--)
+  {
+    res->m[k]=pSubst(id->m[k],n,e);
+    id->m[k]=NULL;
+  }
+  idDelete(&id);
+  return res;
+}
+
+BOOLEAN idHomModule(ideal m, ideal Q, intvec **w)
+{
+  if (w!=NULL) *w=NULL;
+  if ((Q!=NULL) && (!idHomIdeal(Q,NULL))) return FALSE;
+  if (idIs0(m)) return TRUE;
+
+  int i,j,cmax=2,order=0,ord,* diff,* iscom,diffmin=32000;
+  poly p=NULL;
+  int length=IDELEMS(m);
+  polyset P=m->m;
+  polyset F=(polyset)omAlloc(length*sizeof(poly));
+  for (i=length-1;i>=0;i--)
+  {
+    p=F[i]=P[i];
+    cmax=si_max(cmax,pMaxComp(p)+1);
+  }
+  diff = (int *)omAlloc0(cmax*sizeof(int));
+  if (w!=NULL) *w=new intvec(cmax-1);
+  iscom = (int *)omAlloc0(cmax*sizeof(int));
+  i=0;
+  while (i<=length)
+  {
+    if (i<length)
+    {
+      p=F[i];
+      while ((p!=NULL) && (!iscom[pGetComp(p)])) pIter(p);
+    }
+    if ((p==NULL) && (i<length))
+    {
+      i++;
+    }
+    else
+    {
+      if (p==NULL)
+      {
+        i=0;
+        while ((i<length) && (F[i]==NULL)) i++;
+        if (i>=length) break;
+        p = F[i];
+      }
+      if (pLexOrder)
+        order=pTotaldegree(p);
+      else
+      //  order = p->order;
+        order = pFDeg(p);
+      order += diff[pGetComp(p)];
+      p = F[i];
+//Print("Actual p=F[%d]: ",i);pWrite(p);
+      F[i] = NULL;
+      i=0;
+    }
+    while (p!=NULL)
+    {
+      //if (pLexOrder)
+      //  ord=pTotaldegree(p);
+      //else
+      //  ord = p->order;
+      ord = pFDeg(p);
+      if (!iscom[pGetComp(p)])
+      {
+        diff[pGetComp(p)] = order-ord;
+        iscom[pGetComp(p)] = 1;
+/*
+*PrintS("new diff: ");
+*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
+*PrintLn();
+*PrintS("new iscom: ");
+*for (j=0;j<cmax;j++) Print("%d ",iscom[j]);
+*PrintLn();
+*Print("new set %d, order %d, ord %d, diff %d\n",pGetComp(p),order,ord,diff[pGetComp(p)]);
+*/
+      }
+      else
+      {
+/*
+*PrintS("new diff: ");
+*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
+*PrintLn();
+*Print("order %d, ord %d, diff %d\n",order,ord,diff[pGetComp(p)]);
+*/
+        if (order != ord+diff[pGetComp(p)])
+        {
+          omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
+          omFreeSize((ADDRESS) diff,cmax*sizeof(int));
+          omFreeSize((ADDRESS) F,length*sizeof(poly));
+          delete *w;*w=NULL;
+          return FALSE;
+        }
+      }
+      pIter(p);
+    }
+  }
+  omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
+  omFreeSize((ADDRESS) F,length*sizeof(poly));
+  for (i=1;i<cmax;i++) (**w)[i-1]=diff[i];
+  for (i=1;i<cmax;i++)
+  {
+    if (diff[i]<diffmin) diffmin=diff[i];
+  }
+  if (w!=NULL)
+  {
+    for (i=1;i<cmax;i++)
+    {
+      (**w)[i-1]=diff[i]-diffmin;
+    }
+  }
+  omFreeSize((ADDRESS) diff,cmax*sizeof(int));
+  return TRUE;
+}
+
+ideal idJet(ideal i,int d)
+{
+  ideal r=idInit((i->nrows)*(i->ncols),i->rank);
+  r->nrows = i-> nrows;
+  r->ncols = i-> ncols;
+  //r->rank = i-> rank;
+  int k;
+  for(k=(i->nrows)*(i->ncols)-1;k>=0; k--)
+  {
+    r->m[k]=ppJet(i->m[k],d);
+  }
+  return r;
+}
+
+ideal idJetW(ideal i,int d, intvec * iv)
+{
+  ideal r=idInit(IDELEMS(i),i->rank);
+  if (ecartWeights!=NULL)
+  {
+    WerrorS("cannot compute weighted jets now");
+  }
+  else
+  {
+    short *w=iv2array(iv);
+    int k;
+    for(k=0; k<IDELEMS(i); k++)
+    {
+      r->m[k]=ppJetW(i->m[k],d,w);
+    }
+    omFreeSize((ADDRESS)w,(pVariables+1)*sizeof(short));
+  }
+  return r;
+}
+
+int idMinDegW(ideal M,intvec *w)
+{
+  int d=-1;
+  for(int i=0;i<IDELEMS(M);i++)
+  {
+    int d0=pMinDeg(M->m[i],w);
+    if(-1<d0&&(d0<d||d==-1))
+      d=d0;
+  }
+  return d;
+}
+
+ideal idSeries(int n,ideal M,matrix U,intvec *w)
+{
+  for(int i=IDELEMS(M)-1;i>=0;i--)
+  {
+    if(U==NULL)
+      M->m[i]=pSeries(n,M->m[i],NULL,w);
+    else
+    {
+      M->m[i]=pSeries(n,M->m[i],MATELEM(U,i+1,i+1),w);
+      MATELEM(U,i+1,i+1)=NULL;
+    }
+  }
+  if(U!=NULL)
+    idDelete((ideal*)&U);
+  return M;
+}
+
+matrix idDiff(matrix i, int k)
+{
+  int e=MATCOLS(i)*MATROWS(i);
+  matrix r=mpNew(MATROWS(i),MATCOLS(i));
+  int j;
+  for(j=0; j<e; j++)
+  {
+    r->m[j]=pDiff(i->m[j],k);
+  }
+  return r;
+}
+
+matrix idDiffOp(ideal I, ideal J,BOOLEAN multiply)
+{
+  matrix r=mpNew(IDELEMS(I),IDELEMS(J));
+  int i,j;
+  for(i=0; i<IDELEMS(I); i++)
+  {
+    for(j=0; j<IDELEMS(J); j++)
+    {
+      MATELEM(r,i+1,j+1)=pDiffOp(I->m[i],J->m[j],multiply);
+    }
+  }
+  return r;
+}
+
+/*3
+*handles for some ideal operations the ring/syzcomp managment
+*returns all syzygies (componentwise-)shifted by -syzcomp
+*or -syzcomp-1 (in case of ideals as input)
+static ideal idHandleIdealOp(ideal arg,int syzcomp,int isIdeal=FALSE)
+{
+  ring orig_ring=currRing;
+  ring syz_ring=rCurrRingAssure_SyzComp();
+  rSetSyzComp(length);
+
+  ideal s_temp;
+  if (orig_ring!=syz_ring)
+    s_temp=idrMoveR_NoSort(arg,orig_ring);
+  else
+    s_temp=arg;
+
+  ideal s_temp1 = kStd(s_temp,currQuotient,testHomog,&w,NULL,length);
+  if (w!=NULL) delete w;
+
+  if (syz_ring!=orig_ring)
+  {
+    idDelete(&s_temp);
+    rChangeCurrRing(orig_ring);
+  }
+
+  idDelete(&temp);
+  ideal temp1=idRingCopy(s_temp1,syz_ring);
+
+  if (syz_ring!=orig_ring)
+  {
+    rChangeCurrRing(syz_ring);
+    idDelete(&s_temp1);
+    rChangeCurrRing(orig_ring);
+    rKill(syz_ring);
+  }
+
+  for (i=0;i<IDELEMS(temp1);i++)
+  {
+    if ((temp1->m[i]!=NULL)
+    && (pGetComp(temp1->m[i])<=length))
+    {
+      pDelete(&(temp1->m[i]));
+    }
+    else
+    {
+      pShift(&(temp1->m[i]),-length);
+    }
+  }
+  temp1->rank = rk;
+  idSkipZeroes(temp1);
+
+  return temp1;
+}
+*/
+/*2
+* represents (h1+h2)/h2=h1/(h1 intersect h2)
+*/
+ideal idModulo (ideal h2,ideal h1)
+{
+  int i,j,k,rk,flength=0,slength,length;
+  intvec * w;
+  poly p,q;
+
+  if (idIs0(h2))
+    return idFreeModule(si_max(1,h2->ncols));
+  if (!idIs0(h1))
+    flength = idRankFreeModule(h1);
+  slength = idRankFreeModule(h2);
+  length  = si_max(flength,slength);
+  if (length==0)
+  {
+    length = 1;
+  }
+  ideal temp = idInit(IDELEMS(h2),length+IDELEMS(h2));
+  for (i=0;i<IDELEMS(h2);i++)
+  {
+    temp->m[i] = pCopy(h2->m[i]);
+    q = pOne();
+    pSetComp(q,i+1+length);
+    pSetmComp(q);
+    if(temp->m[i]!=NULL)
+    {
+      if (slength==0) pShift(&(temp->m[i]),1);
+      p = temp->m[i];
+      while (pNext(p)!=NULL) pIter(p);
+      pNext(p) = q;
+    }
+    else
+      temp->m[i]=q;
+  }
+  rk = k = IDELEMS(h2);
+  if (!idIs0(h1))
+  {
+    pEnlargeSet(&(temp->m),IDELEMS(temp),IDELEMS(h1));
+    IDELEMS(temp) += IDELEMS(h1);
+    for (i=0;i<IDELEMS(h1);i++)
+    {
+      if (h1->m[i]!=NULL)
+      {
+        temp->m[k] = pCopy(h1->m[i]);
+        if (flength==0) pShift(&(temp->m[k]),1);
+        k++;
+      }
+    }
+  }
+
+  ring orig_ring=currRing;
+  ring syz_ring=rCurrRingAssure_SyzComp();
+  rSetSyzComp(length);
+  ideal s_temp;
+
+  if (syz_ring != orig_ring)
+  {
+    s_temp = idrMoveR_NoSort(temp, orig_ring);
+  }
+  else
+  {
+    s_temp = temp;
+  }
+
+  idTest(s_temp);
+  ideal s_temp1 = kStd(s_temp,currQuotient,testHomog,&w,NULL,length);
+  if (w!=NULL) delete w;
+
+  for (i=0;i<IDELEMS(s_temp1);i++)
+  {
+    if ((s_temp1->m[i]!=NULL)
+    && (pGetComp(s_temp1->m[i])<=length))
+    {
+      pDelete(&(s_temp1->m[i]));
+    }
+    else
+    {
+      pShift(&(s_temp1->m[i]),-length);
+    }
+  }
+  s_temp1->rank = rk;
+  idSkipZeroes(s_temp1);
+
+  if (syz_ring!=orig_ring)
+  {
+    rChangeCurrRing(orig_ring);
+    s_temp1 = idrMoveR_NoSort(s_temp1, syz_ring);
+    rKill(syz_ring);
+    // Hmm ... here seems to be a memory leak
+    // However, simply deleting it causes memory trouble
+    // idDelete(&s_temp);
+  }
+  else
+  {
+    idDelete(&temp);
+  }
+  idTest(s_temp1);
+  return s_temp1;
+}
+
+int idElem(ideal F)
+{
+  int i=0,j=0;
+
+  while(j<IDELEMS(F))
+  {
+   if ((F->m)[j]!=NULL) i++;
+   j++;
+  }
+  return i;
+}
+
+/*
+*computes module-weights for liftings of homogeneous modules
+*/
+intvec * idMWLift(ideal mod,intvec * weights)
+{
+  if (idIs0(mod)) return new intvec(2);
+  int i=IDELEMS(mod);
+  while ((i>0) && (mod->m[i-1]==NULL)) i--;
+  intvec *result = new intvec(i+1);
+  while (i>0)
+  {
+    (*result)[i]=pFDeg(mod->m[i])+(*weights)[pGetComp(mod->m[i])];
+  }
+  return result;
+}
+
+/*2
+*sorts the kbase for idCoef* in a special way (lexicographically
+*with x_max,...,x_1)
+*/
+ideal idCreateSpecialKbase(ideal kBase,intvec ** convert)
+{
+  int i;
+  ideal result;
+
+  if (idIs0(kBase)) return NULL;
+  result = idInit(IDELEMS(kBase),kBase->rank);
+  *convert = idSort(kBase,FALSE);
+  for (i=0;i<(*convert)->length();i++)
+  {
+    result->m[i] = pCopy(kBase->m[(**convert)[i]-1]);
+  }
+  return result;
+}
+
+/*2
+*returns the index of a given monom in the list of the special kbase
+*/
+int idIndexOfKBase(poly monom, ideal kbase)
+{
+  int j=IDELEMS(kbase);
+
+  while ((j>0) && (kbase->m[j-1]==NULL)) j--;
+  if (j==0) return -1;
+  int i=pVariables;
+  while (i>0)
+  {
+    loop
+    {
+      if (pGetExp(monom,i)>pGetExp(kbase->m[j-1],i)) return -1;
+      if (pGetExp(monom,i)==pGetExp(kbase->m[j-1],i)) break;
+      j--;
+      if (j==0) return -1;
+    }
+    if (i==1)
+    {
+      while(j>0)
+      {
+        if (pGetComp(monom)==pGetComp(kbase->m[j-1])) return j-1;
+        if (pGetComp(monom)>pGetComp(kbase->m[j-1])) return -1;
+        j--;
+      }
+    }
+    i--;
+  }
+  return -1;
+}
+
+/*2
+*decomposes the monom in a part of coefficients described by the
+*complement of how and a monom in variables occuring in how, the
+*index of which in kbase is returned as integer pos (-1 if it don't
+*exists)
+*/
+poly idDecompose(poly monom, poly how, ideal kbase, int * pos)
+{
+  int i;
+  poly coeff=pOne(), base=pOne();
+
+  for (i=1;i<=pVariables;i++)
+  {
+    if (pGetExp(how,i)>0)
+    {
+      pSetExp(base,i,pGetExp(monom,i));
+    }
+    else
+    {
+      pSetExp(coeff,i,pGetExp(monom,i));
+    }
+  }
+  pSetComp(base,pGetComp(monom));
+  pSetm(base);
+  pSetCoeff(coeff,nCopy(pGetCoeff(monom)));
+  pSetm(coeff);
+  *pos = idIndexOfKBase(base,kbase);
+  if (*pos<0)
+    pDelete(&coeff);
+  pDelete(&base);
+  return coeff;
+}
+
+/*2
+*returns a matrix A of coefficients with kbase*A=arg
+*if all monomials in variables of how occur in kbase
+*the other are deleted
+*/
+matrix idCoeffOfKBase(ideal arg, ideal kbase, poly how)
+{
+  matrix result;
+  ideal tempKbase;
+  poly p,q;
+  intvec * convert;
+  int i=IDELEMS(kbase),j=IDELEMS(arg),k,pos;
+#if 0
+  while ((i>0) && (kbase->m[i-1]==NULL)) i--;
+  if (idIs0(arg))
+    return mpNew(i,1);
+  while ((j>0) && (arg->m[j-1]==NULL)) j--;
+  result = mpNew(i,j);
+#else
+  result = mpNew(i, j);
+  while ((j>0) && (arg->m[j-1]==NULL)) j--;
+#endif
+
+  tempKbase = idCreateSpecialKbase(kbase,&convert);
+  for (k=0;k<j;k++)
+  {
+    p = arg->m[k];
+    while (p!=NULL)
+    {
+      q = idDecompose(p,how,tempKbase,&pos);
+      if (pos>=0)
+      {
+        MATELEM(result,(*convert)[pos],k+1) =
+            pAdd(MATELEM(result,(*convert)[pos],k+1),q);
+      }
+      else
+        pDelete(&q);
+      pIter(p);
+    }
+  }
+  idDelete(&tempKbase);
+  return result;
+}
+
+/*3
+* searches for units in the components of the module arg and
+* returns the first one
+*/
+static int idReadOutUnits(ideal arg,int* comp)
+{
+  if (idIs0(arg)) return -1;
+  int i=0,j,rk_arg=idRankFreeModule(arg),generator=-1;
+  intvec * componentIsUsed =new intvec(rk_arg+1);
+  poly p,q;
+
+  while ((i<IDELEMS(arg)) && (generator<0))
+  {
+    for (j=rk_arg;j>=0;j--)
+      (*componentIsUsed)[j]=0;
+    p = arg->m[i];
+    while (p!=NULL)
+    {
+      j = pGetComp(p);
+      if ((*componentIsUsed)[j]==0)
+      {
+        if (pLmIsConstantComp(p))
+        {
+          generator = i;
+          (*componentIsUsed)[j] = 1;
+        }
+        else
+        {
+          (*componentIsUsed)[j] = -1;
+        }
+      }
+      else if ((*componentIsUsed)[j]>0)
+      {
+        ((*componentIsUsed)[j])++;
+      }
+      pIter(p);
+    }
+    i++;
+  }
+  i = 0;
+  *comp = -1;
+  for (j=0;j<=rk_arg;j++)
+  {
+    if ((*componentIsUsed)[j]>0)
+    {
+      if ((*comp==-1) || ((*componentIsUsed)[j]<i))
+      {
+        *comp = j;
+        i= (*componentIsUsed)[j];
+      }
+    }
+  }
+  return generator;
+}
+
+static void idDeleteComp(ideal arg,int red_comp)
+{
+  int i,j;
+  poly p;
+
+  for (i=IDELEMS(arg)-1;i>=0;i--)
+  {
+    p = arg->m[i];
+    while (p!=NULL)
+    {
+      j = pGetComp(p);
+      if (j>red_comp)
+      {
+        pSetComp(p,j-1);
+        pSetm(p);
+      }
+      pIter(p);
+    }
+  }
+  (arg->rank)--;
+}
+
+/*2
+* returns the presentation of an isomorphic, minimally
+* embedded  module (arg represents the quotient!)
+*/
+ideal idMinEmbedding(ideal arg,BOOLEAN inPlace)
+{
+  if (idIs0(arg)) return idInit(1,arg->rank);
+  int next_gen,next_comp;
+  ideal res=arg;
+
+  if (!inPlace) res = idCopy(arg);
+  loop
+  {
+    next_gen = idReadOutUnits(res,&next_comp);
+    if (next_gen<0) break;
+    syGaussForOne(res,next_gen,next_comp,0,IDELEMS(res));
+    idDeleteComp(res,next_comp);
+  }
+  idSkipZeroes(res);
+  return res;
+}
+
+/*2
+* transpose a module
+*/
+ideal idTransp(ideal a)
+{
+  int r = a->rank, c = IDELEMS(a);
+  ideal b =  idInit(r,c);
+
+  for (int i=c; i>0; i--)
+  {
+    poly p=a->m[i-1];
+    while(p!=NULL)
+    {
+      poly h=pHead(p);
+      int co=pGetComp(h)-1;
+      pSetComp(h,i);
+      pSetmComp(h);
+      b->m[co]=pAdd(b->m[co],h);
+      pIter(p);
+    }
+  }
+  return b;
+}
+
+intvec * idQHomWeight(ideal id)
+{
+  poly head, tail;
+  int k;
+  int in=IDELEMS(id)-1, ready=0, all=0,
+      coldim=pVariables, rowmax=2*coldim;
+  if (in<0) return NULL;
+  intvec *imat=new intvec(rowmax+1,coldim,0);
+
+  do
+  {
+    head = id->m[in--];
+    if (head!=NULL)
+    {
+      tail = pNext(head);
+      while (tail!=NULL)
+      {
+        all++;
+        for (k=1;k<=coldim;k++)
+          IMATELEM(*imat,all,k) = pGetExpDiff(head,tail,k);
+        if (all==rowmax)
+        {
+          ivTriangIntern(imat, ready, all);
+          if (ready==coldim)
+          {
+            delete imat;
+            return NULL;
+          }
+        }
+        pIter(tail);
+      }
+    }
+  } while (in>=0);
+  if (all>ready)
+  {
+    ivTriangIntern(imat, ready, all);
+    if (ready==coldim)
+    {
+      delete imat;
+      return NULL;
+    }
+  }
+  intvec *result = ivSolveKern(imat, ready);
+  delete imat;
+  return result;
+}
+
+BOOLEAN idIsZeroDim(ideal I)
+{
+  BOOLEAN *UsedAxis=(BOOLEAN *)omAlloc0(pVariables*sizeof(BOOLEAN));
+  int i,n;
+  poly po;
+  BOOLEAN res=TRUE;
+  for(i=IDELEMS(I)-1;i>=0;i--)
+  {
+    po=I->m[i];
+    if ((po!=NULL) &&((n=pIsPurePower(po))!=0)) UsedAxis[n-1]=TRUE;
+  }
+  for(i=pVariables-1;i>=0;i--)
+  {
+    if(UsedAxis[i]==FALSE) {res=FALSE; break;} // not zero-dim.
+  }
+  omFreeSize(UsedAxis,pVariables*sizeof(BOOLEAN));
+  return res;
+}
+
+void idNormalize(ideal I)
+{
+  if (rField_has_simple_inverse()) return; /* Z/p, GF(p,n), R, long R/C */
+  int i;
+  poly p;
+  for(i=IDELEMS(I)-1;i>=0;i--)
+  {
+    p=I->m[i] ;
+    while(p!=NULL)
+    {
+      nNormalize(pGetCoeff(p));
+      pIter(p);
+    }
+  }
+}
Index: kernel/ideals.h
===================================================================
--- kernel/ideals.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/ideals.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,153 @@
+#ifndef IDEALS_H
+#define IDEALS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: ideals.h,v 1.1.1.1 2003-10-06 12:15:53 Singular Exp $ */
+/*
+* ABSTRACT - all basic methods to manipulate ideals
+*/
+#include "structs.h"
+
+#ifdef PDEBUG
+ideal idDBInit (int size, int rank, char *f, int l);
+#define idInit(A,B) idDBInit(A,B,__FILE__,__LINE__)
+#else
+/*- creates an ideal -*/
+ideal idInit (int size, int rank=1);
+#endif
+/*- deletes an ideal -*/
+#define idDelete(h) id_Delete(h, currRing)
+void id_Delete (ideal* h, ring r);
+void id_ShallowDelete (ideal* h, ring r);
+/* Shows an ideal -- mainly for debugging */
+void idShow(ideal id);
+  /*- initialise an ideal -*/
+ideal idMaxIdeal (int deg);
+  /*- initialise the maximal ideal (at 0) -*/
+void idSkipZeroes (ideal ide);
+  /*gives an ideal the minimal possible size*/
+void idNorm(ideal id);
+void idDelMultiples(ideal id);
+void idDelEquals(ideal id);
+void idDelLmEquals(ideal id);
+void idDelDiv(ideal id);
+BOOLEAN idIsConstant(ideal id);
+
+#ifdef PDEBUG
+void idDBTest(ideal h1, int level, char *f,int l);
+#define idTest(A) idDBTest(A, PDEBUG, __FILE__,__LINE__)
+#define idPrint(id) idShow(id)
+#else
+#define idTest(A)  (TRUE)
+#define idPrint(A) ((void)0)
+#endif
+
+#ifdef PDEBUG
+ideal idDBCopy(ideal h1,char *f,int l);
+#define idCopy(A) idDBCopy(A,__FILE__,__LINE__)
+#else
+ideal idCopy (ideal h1);
+#endif
+  /*adds two ideals without simplifying the result*/
+ideal idSimpleAdd (ideal h1,ideal h2);
+  /*adds the quotient ideal*/
+ideal idAdd (ideal h1,ideal h2);
+  /* h1 + h2 */
+ideal idMult (ideal h1,ideal h2);
+  /*hh := h1 * h2*/
+
+BOOLEAN idIs0 (ideal h);
+
+long idRankFreeModule(ideal m, ring lmRing, ring tailRing);
+inline long idRankFreeModule(ideal m, ring r = currRing)
+{return idRankFreeModule(m, r, r);}
+// returns TRUE, if idRankFreeModule(m) > 0
+BOOLEAN idIsModule(ideal m, ring r = currRing);
+BOOLEAN idHomIdeal (ideal id, ideal Q=NULL);
+BOOLEAN idHomModule(ideal m, ideal Q,intvec **w);
+
+ideal idMinBase (ideal h1);
+  /*returns a minimized set of generators of h1*/
+int pLowVar (poly p);
+  /*-the minimal index of used variables - 1-*/
+ideal idDehomogen (ideal id1,poly p,number n);
+  /*dehomogenized the generators of the ideal id1 with the leading
+  monomial of p replaced by n*/
+void pShift (poly * p,int i);
+  /*- verschiebt die Indizes der Modulerzeugenden um i -*/
+void    idInitChoise (int r,int beg,int end,BOOLEAN *endch,int * choise);
+void    idGetNextChoise (int r,int end,BOOLEAN *endch,int * choise);
+int     idGetNumberOfChoise(int t, int d, int begin, int end, int * choise);
+
+int     binom (int n,int r);
+
+ideal   idFreeModule (int i);
+
+ideal   idSect (ideal h1,ideal h2);
+ideal   idMultSect(resolvente arg, int length);
+
+//ideal   idSyzygies (ideal h1, tHomog h,intvec **w);
+ideal   idSyzygies (ideal h1, tHomog h,intvec **w, BOOLEAN setSyzComp=TRUE,
+                    BOOLEAN setRegularity=FALSE, int *deg = NULL);
+ideal   idLiftStd  (ideal h1, matrix *m, tHomog h=testHomog);
+
+ideal   idLift (ideal mod, ideal sumod,ideal * rest=NULL,
+             BOOLEAN goodShape=FALSE, BOOLEAN isSB=TRUE,BOOLEAN divide=FALSE,
+             matrix *unit=NULL);
+
+void idLiftW(ideal P,ideal Q,int n,matrix &T, ideal &R, short *w= NULL );
+
+intvec * idMWLift(ideal mod,intvec * weights);
+
+ideal   idQuot (ideal h1,ideal h2,
+                BOOLEAN h1IsStb=FALSE, BOOLEAN resultIsIdeal=FALSE);
+
+ideal   idPower(ideal gid,int deg);
+
+//ideal   idElimination (ideal h1,poly delVar);
+ideal   idElimination (ideal h1,poly delVar, intvec *hilb=NULL);
+
+ideal   idMinors(matrix a, int ar, ideal R=NULL);
+
+ideal   idCompactify(ideal id);
+
+ideal idMinEmbedding(ideal arg,BOOLEAN inPlace=FALSE);
+
+ideal   idHead(ideal h);
+
+ideal   idHomogen(ideal h, int varnum);
+
+BOOLEAN idIsSubModule(ideal id1,ideal id2);
+
+ideal   idVec2Ideal(poly vec);
+
+ideal   idMatrix2Module(matrix mat);
+
+matrix  idModule2Matrix(ideal mod);
+
+matrix  idModule2formatedMatrix(ideal mod,int rows, int cols);
+
+ideal   idSubst(ideal i, int n, poly e);
+
+ideal   idJet(ideal i,int d);
+ideal   idJetW(ideal i,int d, intvec * iv);
+int idMinDegW(ideal M,intvec *w);
+ideal   idSeries(int n,ideal M,matrix U=NULL,intvec *w=NULL);
+
+BOOLEAN idIsZeroDim(ideal i);
+matrix  idDiff(matrix i, int k);
+matrix  idDiffOp(ideal I, ideal J,BOOLEAN multiply=TRUE);
+
+intvec *idSort(ideal id,BOOLEAN nolex=TRUE);
+ideal   idModulo (ideal h1,ideal h2);
+int     idElem(ideal F);
+matrix  idCoeffOfKBase(ideal arg, ideal kbase, poly how);
+ideal   idTransp(ideal a);
+
+intvec *idQHomWeight(ideal id);
+
+void    idNormalize(ideal id);
+
+ideal idXXX (ideal  h1, int k);
+#endif
Index: kernel/install-sh
===================================================================
--- kernel/install-sh	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/install-sh	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,246 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	true
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+	else
+		instcmd=mkdir
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+# obachman 6/15/98
+# Here is an ugly fix for a bug in cygwin
+# '[ test -f $src ]' evaluates to true, even if only $src.exe exists
+# However 'cp $src $dst' can  not find $src, if only $src.exe exists
+	if test -f "$src.exe" && test -x "$src.exe"; then
+		src="$src.exe"
+		true
+	elif [ -f $src -o -d $src ]
+	then
+		true
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		true
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		true
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='	
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		true
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		echo "basename $dst $transformbasename | sed $transformarg$transformbasename"
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		true
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
Index: kernel/intvec.cc
===================================================================
--- kernel/intvec.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/intvec.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,774 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/* $Id: intvec.cc,v 1.1.1.1 2003-10-06 12:15:55 Singular Exp $ */
+/*
+* ABSTRACT: class intvec: lists/vectors of integers
+*/
+#ifndef INTVEC_CC
+#define INTVEC_CC
+#include "mod2.h"
+#include "structs.h"
+#include "febase.h"
+#include "intvec.h"
+#include "omalloc.h"
+
+/*0 implementation*/
+
+
+intvec::intvec(intvec* iv)
+{
+  row = iv->rows();
+  col = iv->cols();
+  v   = (int *)omAlloc(sizeof(int)*row*col);
+  for (int i=0; i<row*col; i++)
+  {
+    v[i] = (*iv)[i];
+  }
+}
+
+intvec::intvec(int s, int e)
+{
+  int inc;
+  col = 1;
+  if (s<e)
+  {
+    row =  e-s+1;
+    inc =  1;
+  }
+  else
+  {
+    row = s-e+1;
+    inc = -1;
+  }
+  v = (int *)omAlloc(sizeof(int)*row);
+  for (int i=0; i<row; i++)
+  {
+    v[i] = s;
+    s+=inc;
+  }
+}
+
+intvec::intvec(int r, int c, int init)
+{
+  row = r;
+  col = c;
+  int l = r*c;
+  if ((r>0) && (c>0))
+    v = (int *)omAlloc(sizeof(int)*l);
+  else
+    v = NULL;
+  for (int i=0; i<l; i++)
+  {
+    v[i] = init;
+  }
+}
+
+char * intvec::ivString(int not_mat,int spaces, int dim)
+{
+  StringSetS("");
+  if ((col == 1)&&(not_mat))
+  {
+    int i=0;
+    for (; i<row-1; i++)
+    {
+      StringAppend("%d,",v[i]);
+    }
+    if (i<row)
+    {
+      StringAppend("%d",v[i]);
+    }
+  }
+  else
+  {
+    for (int j=0; j<row; j++)
+    {
+      if (j<row-1)
+      {
+        for (int i=0; i<col; i++)
+        {
+          StringAppend("%d%c",v[j*col+i],',');
+        }
+      }
+      else
+      {
+        for (int i=0; i<col; i++)
+        {
+          StringAppend("%d%c",v[j*col+i],i<col-1 ? ',' : ' ');
+        }
+      }
+      if (j+1<row)
+      {
+        if (dim > 1) StringAppendS("\n");
+        if (spaces>0) StringAppend("%-*.*s",spaces,spaces," ");
+      }
+    }
+  }
+  return StringAppendS("");
+}
+
+void intvec::resize(int new_length)
+{
+  assume(new_length > 0 && col == 1);
+  v = (int*) omRealloc0Size(v, row*sizeof(int), new_length*sizeof(int));
+  row = new_length;
+}
+
+char * intvec::String(int dim)
+{
+  return omStrDup(ivString(1, 0, dim));
+}
+
+void intvec::show(int notmat,int spaces)
+{
+  if (spaces>0)
+    Print("%-*.*s%s",spaces,spaces," ",ivString(notmat,spaces));
+  else
+    PrintS(ivString(notmat,0));
+}
+
+void intvec::operator+=(int intop)
+{
+  for (int i=0; i<row*col; i++) { v[i] += intop; }
+}
+
+void intvec::operator-=(int intop)
+{
+  for (int i=0; i<row*col; i++) { v[i] -= intop; }
+}
+
+void intvec::operator*=(int intop)
+{
+  for (int i=0; i<row*col; i++) { v[i] *= intop; }
+}
+
+void intvec::operator/=(int intop)
+{
+  if (intop == 0) return;
+  int bb=ABS(intop);
+  for (int i=0; i<row*col; i++)
+  {
+    int r=v[i];
+    int c=r%bb;
+    if (c<0) c+=bb;
+    r=(r-c)/intop;
+    v[i]=r;
+  }
+}
+
+void intvec::operator%=(int intop)
+{
+  if (intop == 0) return;
+  int bb=ABS(intop);
+  for (int i=0; i<row*col; i++)
+  {
+    int r=v[i];
+    int c=r%bb;
+    if (c<0) c+=bb;
+    v[i]=c;
+  }
+}
+
+int intvec::compare(intvec* op)
+{
+  if ((col!=1) ||(op->cols()!=1))
+  {
+    if((col!=op->cols())
+    || (row!=op->rows()))
+      return -2;
+  }
+  int i;
+  for (i=0; i<si_min(length(),op->length()); i++)
+  {
+    if (v[i] > (*op)[i])
+      return 1;
+    if (v[i] < (*op)[i])
+      return -1;
+  }
+  // this can only happen for intvec: (i.e. col==1)
+  for (; i<row; i++)
+  {
+    if (v[i] > 0)
+      return 1;
+    if (v[i] < 0)
+      return -1;
+  }
+  for (; i<op->rows(); i++)
+  {
+    if (0 > (*op)[i])
+      return 1;
+    if (0 < (*op)[i])
+      return -1;
+  }
+  return 0;
+}
+int intvec::compare(int o)
+{
+  for (int i=0; i<row*col; i++)
+  {
+    if (v[i] <o) return -1;
+    if (v[i] >o) return 1;
+  }
+  return 0;
+}
+
+intvec * ivCopy(intvec * o)
+{
+  intvec * iv=new intvec(o);
+  return iv;
+}
+
+intvec * ivAdd(intvec * a, intvec * b)
+{
+  intvec * iv;
+  int mn, ma, i;
+  if (a->cols() != b->cols()) return NULL;
+  mn = si_min(a->rows(),b->rows());
+  ma = si_max(a->rows(),b->rows());
+  if (a->cols() == 1)
+  {
+    iv = new intvec(ma);
+    for (i=0; i<mn; i++) (*iv)[i] = (*a)[i] + (*b)[i];
+    if (ma > mn)
+    {
+      if (ma == a->rows())
+      {
+        for(i=mn; i<ma; i++) (*iv)[i] = (*a)[i];
+      }
+      else
+      {
+        for(i=mn; i<ma; i++) (*iv)[i] = (*b)[i];
+      }
+    }
+    return iv;
+  }
+  if (mn != ma) return NULL;
+  iv = new intvec(a);
+  for (i=0; i<mn*a->cols(); i++) { (*iv)[i] += (*b)[i]; }
+  return iv;
+}
+
+intvec * ivSub(intvec * a, intvec * b)
+{
+  intvec * iv;
+  int mn, ma, i;
+  if (a->cols() != b->cols()) return NULL;
+  mn = si_min(a->rows(),b->rows());
+  ma = si_max(a->rows(),b->rows());
+  if (a->cols() == 1)
+  {
+    iv = new intvec(ma);
+    for (i=0; i<mn; i++) (*iv)[i] = (*a)[i] - (*b)[i];
+    if (ma > mn)
+    {
+      if (ma == a->rows())
+      {
+        for(i=mn; i<ma; i++) (*iv)[i] = (*a)[i];
+      }
+      else
+      {
+        for(i=mn; i<ma; i++) (*iv)[i] = -(*b)[i];
+      }
+    }
+    return iv;
+  }
+  if (mn != ma) return NULL;
+  iv = new intvec(a);
+  for (i=0; i<mn*a->cols(); i++) { (*iv)[i] -= (*b)[i]; }
+  return iv;
+}
+
+intvec * ivTranp(intvec * o)
+{
+  int i, j, r = o->rows(), c = o->cols();
+  intvec * iv= new intvec(c, r, 0);
+  for (i=0; i<r; i++)
+  {
+    for (j=0; j<c; j++)
+      (*iv)[j*r+i] = (*o)[i*c+j];
+  }
+  return iv;
+}
+
+int ivTrace(intvec * o)
+{
+  int i, s = 0, m = si_min(o->rows(),o->cols()), c = o->cols();
+  for (i=0; i<m; i++)
+  {
+    s += (*o)[i*c+i];
+  }
+  return s;
+}
+
+intvec * ivMult(intvec * a, intvec * b)
+{
+  int i, j, k, sum,
+      ra = a->rows(), ca = a->cols(),
+      rb = b->rows(), cb = b->cols();
+  intvec * iv;
+  if (ca != rb) return NULL;
+  iv = new intvec(ra, cb, 0);
+  for (i=0; i<ra; i++)
+  {
+    for (j=0; j<cb; j++)
+    {
+      sum = 0;
+      for (k=0; k<ca; k++)
+        sum += (*a)[i*ca+k]*(*b)[k*cb+j];
+      (*iv)[i*cb+j] = sum;
+    }
+  }
+  return iv;
+}
+
+/*2
+*computes a triangular matrix 
+*/
+//void ivTriangMat(intvec * imat)
+//{
+//  int i=0,j=imat->rows(),k=j*imat->cols()-1;
+//
+//  ivTriangIntern(imat,i,j);
+//  i *= imat->cols();
+//  for(j=k;j>=i;j--)
+//    (*imat)[j] = 0; 
+//}
+
+/* def. internals */
+static int ivColPivot(intvec *, int, int, int, int);
+static void ivNegRow(intvec *, int);
+static void ivSaveRow(intvec *, int);
+static void ivSetRow(intvec *, int, int);
+static void ivFreeRow(intvec *, int, int);
+static void ivReduce(intvec *, int, int, int, int);
+static void ivZeroElim(intvec *,int, int, int &);
+static void ivRowContent(intvec *, int, int);
+static void ivKernFromRow(intvec *, intvec *, intvec *,
+                          int, int, int);
+static intvec * ivOptimizeKern(intvec *);
+static int ivGcd(int, int);
+static void ivOptRecursive(intvec *, intvec *, intvec *,
+                          int &, int &, int);
+static void ivOptSolve(intvec *, intvec *, int &, int &);
+static void ivContent(intvec *);
+static int ivL1Norm(intvec *);
+static int ivCondNumber(intvec *, int); 
+
+/* Triangulierung in intmat.cc */
+void ivTriangIntern(intvec *imat, int &ready, int &all)
+{
+  int rpiv, colpos=0, rowpos=0;
+  int ia=ready, ie=all;
+
+  do
+  {
+    rowpos++;
+    do
+    {
+      colpos++;
+      rpiv = ivColPivot(imat, colpos, rowpos, ia, ie);
+    } while (rpiv==0);
+    if (rpiv>ia)
+    {
+      if (rowpos!=rpiv)
+      {
+        ivSaveRow(imat, rpiv);
+        ivFreeRow(imat, rowpos, rpiv);
+        ivSetRow(imat, rowpos, colpos);
+        rpiv = rowpos;
+      }
+      ia++;
+      if (ia==imat->cols())
+      {
+        ready = ia;
+        all = ie;
+        return;
+      }
+    }
+    ivReduce(imat, rpiv, colpos, ia, ie);
+    ivZeroElim(imat, colpos, ia, ie);
+  } while (ie>ia);
+  ready = ia;
+  all = ie;
+}
+
+/* Kernberechnung in intmat.cc */
+intvec * ivSolveKern(intvec *imat, int dimtr)
+{
+  int d=imat->cols();
+  int kdim=d-dimtr;
+  intvec *perm = new intvec(dimtr+1);
+  intvec *kern = new intvec(kdim,d,0);
+  intvec *res;
+  int c, cp, r, t;
+
+  t = kdim;
+  c = 1;
+  for (r=1;r<=dimtr;r++)
+  {
+    while (IMATELEM(*imat,r,c)==0) c++;
+    (*perm)[r] = c;
+    c++;
+  }
+  c = d;
+  for (r=dimtr;r>0;r--)
+  {
+    cp = (*perm)[r];
+    if (cp!=c)
+    {
+      ivKernFromRow(kern, imat, perm, t, r, c);
+      t -= (c-cp);
+      if (t==0)
+        break;
+      c = cp-1;
+    }
+    else
+      c--;
+  }
+  if (kdim>1)
+    res = ivOptimizeKern(kern);
+  else
+    res = ivTranp(kern);
+  delete kern;
+  delete perm;
+  return res;
+}
+
+/* internals */
+static int ivColPivot(intvec *imat, int colpos, int rowpos, int ready, int all)
+{
+  int rpiv;
+
+  if (IMATELEM(*imat,rowpos,colpos)!=0)
+    return rowpos;
+  for (rpiv=ready+1;rpiv<=all;rpiv++)
+  {
+    if (IMATELEM(*imat,rpiv,colpos)!=0)
+      return rpiv;
+  }
+  return 0;
+}
+
+static void ivNegRow(intvec *imat, int rpiv)
+{
+  int i;
+  for (i=imat->cols();i!=0;i--)
+    IMATELEM(*imat,rpiv,i) = -(IMATELEM(*imat,rpiv,i));
+}
+
+static void ivSaveRow(intvec *imat, int rpiv)
+{
+  int i, j=imat->rows();
+
+  for (i=imat->cols();i!=0;i--)
+    IMATELEM(*imat,j,i) = IMATELEM(*imat,rpiv,i);
+}
+
+static void ivSetRow(intvec *imat, int rowpos, int colpos)
+{
+  int i, j=imat->rows();
+
+  for (i=imat->cols();i!=0;i--)
+    IMATELEM(*imat,rowpos,i) = IMATELEM(*imat,j,i);
+  ivRowContent(imat, rowpos, colpos);
+}
+
+static void ivFreeRow(intvec *imat, int rowpos, int rpiv)
+{
+  int i, j;
+
+  for (j=rpiv-1;j>=rowpos;j--)
+  {
+    for (i=imat->cols();i!=0;i--)
+      IMATELEM(*imat,j+1,i) = IMATELEM(*imat,j,i);
+  }
+}
+
+static void ivReduce(intvec *imat, int rpiv, int colpos,
+                     int ready, int all)
+{
+  int tgcd, ce, m1, m2, j, i;
+  int piv = IMATELEM(*imat,rpiv,colpos);
+
+  for (j=all;j>ready;j--)
+  {
+    ce = IMATELEM(*imat,j,colpos);
+    if (ce!=0)
+    {
+      IMATELEM(*imat,j,colpos) = 0;
+      m1 = piv;
+      m2 = ce;
+      tgcd = ivGcd(m1, m2);
+      if (tgcd != 1)
+      {
+        m1 /= tgcd;
+        m2 /= tgcd;
+      }
+      for (i=imat->cols();i>colpos;i--)
+      {
+        IMATELEM(*imat,j,i) = IMATELEM(*imat,j,i)*m1-
+                              IMATELEM(*imat,rpiv,i)*m2;
+      }
+      ivRowContent(imat, j, colpos+1);
+    }
+  }
+}
+
+static void ivZeroElim(intvec *imat, int colpos,
+                     int ready, int &all)
+{
+  int j, i, k, l;
+
+  k = ready;
+  for (j=ready+1;j<=all;j++)
+  {
+    for (i=imat->cols();i>colpos;i--)
+    {
+      if (IMATELEM(*imat,j,i)!=0)
+      {
+        k++;
+        if (k<j)
+        {
+          for (l=imat->cols();l>colpos;l--)
+            IMATELEM(*imat,k,l) = IMATELEM(*imat,j,l);
+        }
+        break;
+      }
+    }
+  }
+  all = k;
+}
+
+static void ivRowContent(intvec *imat, int rowpos, int colpos)
+{
+  int tgcd, m;
+  int i=imat->cols();
+
+  loop
+  {
+    tgcd = IMATELEM(*imat,rowpos,i--);
+    if (tgcd!=0) break;
+    if (i<colpos) return;
+  }
+  if (tgcd<0) tgcd = -tgcd;
+  if (tgcd==1) return;
+  loop
+  {
+    m = IMATELEM(*imat,rowpos,i--);
+    if (m!=0) tgcd= ivGcd(tgcd, m);
+    if (tgcd==1) return;
+    if (i<colpos) break;
+  }
+  for (i=imat->cols();i>=colpos;i--)
+    IMATELEM(*imat,rowpos,i) /= tgcd;
+}
+
+static void ivKernFromRow(intvec *kern, intvec *imat,
+                          intvec *perm, int pos, int r, int c)
+{
+  int piv, cp, g, i, j, k, s;
+
+  for (i=c;i>(*perm)[r];i--)
+  {
+    IMATELEM(*kern,pos,i) = 1;
+    for (j=r;j!=0;j--)
+    {
+      cp = (*perm)[j];
+      s=0;
+      for(k=c;k>cp;k--)
+        s += IMATELEM(*imat,j,k)*IMATELEM(*kern,pos,k);
+      if (s!=0)
+      {
+        piv = IMATELEM(*imat,j,cp);
+        g = ivGcd(piv,s);
+        if (g!=1)
+        {
+          s /= g;
+          piv /= g;
+        }
+        for(k=c;k>cp;k--)
+          IMATELEM(*kern,pos,k) *= piv;
+        IMATELEM(*kern,pos,cp) = -s;
+        ivRowContent(kern,pos,cp);
+      }
+    }
+    if (IMATELEM(*kern,pos,i)<0)
+      ivNegRow(kern,pos);
+    pos--;
+  }
+}
+
+static int ivGcd(int a,int b)
+{
+  int x;
+
+  if (a<0) a=-a;
+  if (b<0) b=-b;
+  if (b>a)
+  {
+    x=b;
+    b=a;
+    a=x;
+  }
+  while (b!=0)
+  {
+    x = a % b;
+    a = b;
+    b = x;
+  }
+  return a;
+}
+
+static intvec * ivOptimizeKern(intvec *kern)
+{
+  int i,l,j,c=kern->cols(),r=kern->rows();
+  intvec *res=new intvec(c);
+
+  if (TEST_OPT_PROT)
+    Warn(" %d linear independent solutions\n",r);
+  for (i=r;i>1;i--)
+  {
+    for (j=c;j>0;j--)
+    {
+      (*res)[j-1] += IMATELEM(*kern,i,j);
+    }
+  }
+  ivContent(res);
+  if (r<11)
+  {
+    l = ivCondNumber(res,-c);
+    j = ivL1Norm(res);
+    ivOptRecursive(res, NULL, kern, l, j, r);
+  }
+  return res;
+}
+
+static void ivOptRecursive(intvec *res, intvec *w, intvec *kern,
+                          int &l, int &j, int pos)
+{
+  int m, k, d;
+  intvec *h;
+
+  d=kern->rows();
+  d=96/(d*d);
+  if (d<3) d=3;
+  if (w!=0)
+    h = new intvec(w);
+  else
+    h = new intvec(res->rows());
+  for (m=d;m>0;m--)
+  {
+    for(k=h->rows()-1;k>=0;k--)
+      (*h)[k] += IMATELEM(*kern,pos,k+1);
+    if(pos>1)
+      ivOptRecursive(res, h, kern, l, j, pos-1);
+    else
+      ivOptSolve(res, h, l, j);
+  }
+  delete h;
+  if (pos>1)
+    ivOptRecursive(res, w, kern, l, j, pos-1);
+  else if (w!=NULL)
+    ivOptSolve(res, w, l, j);
+}
+
+static void ivOptSolve(intvec *res, intvec *w, int &l, int &j)
+{
+  int l0, j0, k;
+
+  l0 = ivCondNumber(w, l);
+  if (l0==l)
+  {
+    ivContent(w);
+    j0 = ivL1Norm(w);
+    if(j0<j)
+    {
+      j = j0;
+      for(k=w->rows()-1;k>=0;k--)
+        (*res)[k] = (*w)[k];
+    }
+    return;
+  }
+  if(l0>l)
+  {
+    l = l0;
+    ivContent(w);
+    j = ivL1Norm(w);
+    for(k=w->rows()-1;k>=0;k--)
+      (*res)[k] = (*w)[k];
+  } 
+}
+
+static int ivL1Norm(intvec *w)
+{
+  int i, j, s = 0;
+
+  for (i=w->rows()-1;i>=0;i--)
+  {
+    j = (*w)[i];
+    if (j>0)
+      s += j;
+    else
+      s -= j;
+  }
+  return s;
+}
+
+static int ivCondNumber(intvec *w, int l)
+{
+  int l0=0, i;
+
+  if (l<0)
+  {
+    for (i=w->rows()-1;i>=0;i--)
+    {
+      if ((*w)[i]<0) l0--;
+    }
+    if (l0==0)
+    {
+      for (i=w->rows()-1;i>=0;i--)
+      {
+        if ((*w)[i]>0) l0++;
+      }
+    }
+    return l0;
+  }
+  else
+  {
+    for (i=w->rows()-1;i>=0;i--)
+    {
+      if ((*w)[i]<0) return -1;
+    }
+    for (i=w->rows()-1;i>=0;i--)
+    {
+      if ((*w)[i]>0) l0++;
+    }
+    return l0;
+  }
+}
+
+static void ivContent(intvec *w)
+{
+  int tgcd, m;
+  int i=w->rows()-1;
+
+  loop
+  {
+    tgcd = (*w)[i--];
+    if (tgcd!=0) break;
+    if (i<0) return;
+  }
+  if (tgcd<0) tgcd = -tgcd;
+  if (tgcd==1) return;
+  loop
+  {
+    m = (*w)[i--];
+    if (m!=0) tgcd= ivGcd(tgcd, m);
+    if (tgcd==1) return;
+    if (i<0) break;
+  }
+  for (i=w->rows()-1;i>=0;i--)
+    (*w)[i] /= tgcd;
+}
+
+#endif
Index: kernel/intvec.h
===================================================================
--- kernel/intvec.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/intvec.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,97 @@
+#ifndef INTVEC_H
+#define INTVEC_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: intvec.h,v 1.1.1.1 2003-10-06 12:15:55 Singular Exp $ */
+/*
+* ABSTRACT: class intvec: lists/vectors of integers
+*/
+#include <string.h>
+#include "omalloc.h"
+#include "febase.h"
+
+class intvec
+{
+private:
+  int *v;
+  int row;
+  int col;
+public:
+
+  intvec(int l = 1)
+    {
+      v = (int *)omAlloc0(sizeof(int)*l);
+      row = l;
+      col = 1;
+    }
+  intvec(int s, int e);
+  intvec(int r, int c, int init);
+  intvec(intvec* iv);
+
+  void resize(int new_length);
+  int range(int i)
+    { return ((i<row) && (i>=0) && (col==1)); }
+  int range(int i, int j)
+    { return ((i<row) && (i>=0) && (j<col) && (j>=0)); }
+  int& operator[](int i)
+    {
+#ifndef NDEBUG
+      if((i<0)||(i>=row*col))
+      {
+        Werror("wrong intvec index:%d\n",i);
+      }
+#endif
+      return v[i];
+    }
+#define IMATELEM(M,I,J) (M)[(I-1)*(M).cols()+J-1]
+  void operator+=(int intop);
+  void operator-=(int intop);
+  void operator*=(int intop);
+  void operator/=(int intop);
+  void operator%=(int intop);
+  // -2: not compatible, -1: <, 0:=, 1: >
+  int compare(intvec* o);
+  int compare(int o);
+  int  length() const { return col*row; }
+  int  cols() const { return col; }
+  int  rows() const { return row; }
+  void length(int l) { row = l; col = 1; }
+  void show(int notmat=1,int spaces=0);
+  void makeVector() { row*=col;col=1; }
+  // keiner (ausser obachman) darf das folgenden benutzen !!!
+  int * ivGetVec() { return v; }
+  char * String(int dim = 2);
+  char * ivString(int mat=0,int spaces=0, int dim=2);
+  ~intvec()
+    {
+      if (v!=NULL)
+      {
+        omFreeSize((ADDRESS)v,sizeof(int)*row*col);
+        v=NULL;
+      }
+    }
+  void ivTEST()
+    {
+      omCheckAddrSize((ADDRESS)v,sizeof(int)*row*col);
+    }
+};
+intvec * ivCopy(intvec * o);
+intvec * ivAdd(intvec * a, intvec * b);
+intvec * ivSub(intvec * a, intvec * b);
+intvec * ivTranp(intvec * o);
+int      ivTrace(intvec * o);
+intvec * ivMult(intvec * a, intvec * b);
+//void     ivTriangMat(intvec * imat);
+void     ivTriangIntern(intvec * imat, int &ready, int &all);
+intvec * ivSolveKern(intvec * imat, int ready);
+
+
+#ifdef MDEBUG
+#define ivTest(v) v->ivTEST()
+#else
+#define ivTest(v)   ((void)0)
+#endif
+#undef INLINE_THIS
+
+#endif
Index: kernel/ipconv.cc
===================================================================
--- kernel/ipconv.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/ipconv.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,390 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: ipconv.cc,v 1.1.1.1 2003-10-06 12:15:55 Singular Exp $ */
+/*
+* ABSTRACT: automatic type conversions
+*/
+
+#include "mod2.h"
+#include "tok.h"
+#include "ipid.h"
+#include "intvec.h"
+#include "omalloc.h"
+#include "febase.h"
+#include "polys.h"
+#include "ideals.h"
+#include "subexpr.h"
+#include "numbers.h"
+#include "matpol.h"
+#include "silink.h"
+#include "syz.h"
+#include "ipconv.h"
+
+typedef void *   (*iiConvertProc)(void * data);
+struct sConvertTypes
+{
+  int i_typ;
+  int o_typ;
+  iiConvertProc p;
+};
+
+// all of these static conversion routines work destructive on their input
+
+static void * iiI2P(void *data)
+{
+  poly p=pISet((int)data);
+  return (void *)p;
+}
+
+static void * iiI2V(void *data)
+{
+  poly p=pISet((int)data);
+  if (p!=NULL) pSetComp(p,1);
+  return (void *)p;
+}
+
+static void * iiI2Id(void *data)
+{
+  ideal I=idInit(1,1);
+  I->m[0]=pISet((int)data);
+  return (void *)I;
+}
+
+static void * iiP2V(void *data)
+{
+  poly p=(poly)data;
+  if (p!=NULL) pSetCompP(p,1);
+  return (void *)p;
+}
+
+static void * iiP2Id(void *data)
+{
+  ideal I=idInit(1,1);
+
+  I->m[0]=(poly)data;
+  if (data!=NULL)
+  {
+    poly p=(poly)data;
+    if (pGetComp(p)!=0) I->rank=pMaxComp(p);
+#ifdef DRING
+    else if (pDRING)
+    {
+      while (p!=NULL)
+      {
+        pdSetDFlag(p,1);
+        pSetm(p);
+        pIter(p);
+      }
+    }
+#endif
+  }
+  return (void *)I;
+}
+
+static void * iiV2Ma(void *data)
+{
+  matrix m=(matrix)idVec2Ideal((poly)data);
+  int h=MATCOLS(m);
+  MATCOLS(m)=MATROWS(m);
+  MATROWS(m)=h;
+  m->rank=h;
+  pDelete((poly *)&data);
+  return (void *)m;
+}
+
+static void * iiDummy(void *data)
+{
+  return data;
+}
+
+static void * iiMo2Ma(void *data)
+{
+  void *res=idModule2Matrix((ideal)data);
+  return res;
+}
+
+static void * iiMa2Mo(void *data)
+{
+  void *res=idMatrix2Module((matrix)data);
+  return res;
+}
+
+static void * iiI2Iv(void *data)
+{
+  intvec *iv=new intvec((int)data,(int)data);
+  return (void *)iv;
+}
+
+static void * iiI2N(void *data)
+{
+  number n=nInit((int)data);
+  return (void *)n;
+}
+
+static void * iiIm2Ma(void *data)
+{
+  int i, j;
+  intvec *iv = (intvec *)data;
+  matrix m = mpNew(iv->rows(), iv->cols());
+
+  for (i=iv->rows(); i>0; i--)
+  {
+    for (j=iv->cols(); j>0; j--)
+    {
+      MATELEM(m, i, j) = pISet(IMATELEM(*iv, i, j));
+    }
+  }
+  delete iv;
+  return (void *)m;
+}
+
+static void * iiN2P(void *data)
+{
+  poly p=NULL;
+  if (!nIsZero((number)data))
+  {
+    p=pOne();
+    pSetCoeff(p,(number)data);
+  }
+  //else
+  //{
+  //  nDelete((number *)&data);
+  //}
+  return (void *)p;
+}
+
+static void * iiN2Ma(void *data)
+{
+  ideal I=idInit(1,1);
+  if (!nIsZero((number)data))
+  {
+    poly p=pOne();
+    pSetCoeff(p,(number)data);
+    I->m[0]=p;
+  }
+  //else
+  //{
+  //  nDelete((number *)&data);
+  //}
+  return (void *)I;
+}
+
+static void * iiS2Link(void *data)
+{
+  si_link l=(si_link)omAlloc0Bin(ip_link_bin);
+  slInit(l, (char *) data);
+  omFree((ADDRESS)data);
+  return (void *)l;
+}
+
+static void * iiR2L(void * data)
+{
+  syStrategy tmp=(syStrategy)data;
+  return  (void *)syConvRes(tmp,TRUE);
+}
+
+static void * iiL2R(void * data)
+{
+  return (void *)syConvList((lists)data,TRUE);
+}
+
+//
+// automatic conversions:
+//
+struct sConvertTypes dConvertTypes[] =
+{
+//   input type       output type     convert procedure
+//  int -> number
+   { INT_CMD,         NUMBER_CMD,     iiI2N },
+//  int -> poly
+   { INT_CMD,         POLY_CMD,       iiI2P },
+//  int -> vector
+   { INT_CMD,         VECTOR_CMD,     iiI2V },
+//  int -> ideal
+   { INT_CMD,         IDEAL_CMD,      iiI2Id },
+//  int -> matrix
+   { INT_CMD,         MATRIX_CMD,     iiI2Id },
+//  int -> intvec
+   { INT_CMD,         INTVEC_CMD,     iiI2Iv },
+//  intvec -> intmat
+   { INTVEC_CMD,      INTMAT_CMD,     iiDummy},
+//  intvec -> matrix
+   { INTVEC_CMD,      MATRIX_CMD,     iiIm2Ma },
+//  intmat -> matrix
+   { INTMAT_CMD,      MATRIX_CMD,     iiIm2Ma },
+//  number -> poly
+   { NUMBER_CMD,      POLY_CMD,       iiN2P  },
+//  number -> matrix
+   { NUMBER_CMD,      MATRIX_CMD,     iiN2Ma  },
+//  number -> ideal
+//  number -> vector
+//  number -> module
+//  poly -> number
+//  poly -> ideal
+   { POLY_CMD,        IDEAL_CMD,      iiP2Id },
+//  poly -> vector
+   { POLY_CMD,        VECTOR_CMD,     iiP2V },
+//  poly -> matrix
+   { POLY_CMD,        MATRIX_CMD,     iiP2Id },
+//  vector -> module
+   { VECTOR_CMD,      MODUL_CMD,      iiP2Id },
+//  vector -> matrix
+   { VECTOR_CMD,      MATRIX_CMD,     iiV2Ma },
+//  ideal -> module
+   { IDEAL_CMD,       MODUL_CMD,      iiMa2Mo },
+//  ideal -> matrix
+   { IDEAL_CMD,       MATRIX_CMD,     iiDummy },
+//  module -> matrix
+   { MODUL_CMD,       MATRIX_CMD,     iiMo2Ma },
+//  matrix -> ideal
+//  matrix -> module
+   { MATRIX_CMD,      MODUL_CMD,      iiMa2Mo },
+//  intvec
+//  link
+   { STRING_CMD,      LINK_CMD,       iiS2Link },
+// resolution -> list
+   { RESOLUTION_CMD,  LIST_CMD,       iiR2L },
+// list -> resolution
+   { LIST_CMD,        RESOLUTION_CMD, iiL2R },
+//  end of list
+   { 0,               0,              NULL }
+};
+
+/*2
+* try to convert 'input' of type 'inputType' to 'output' of type 'outputType'
+* return FALSE on success
+*/
+BOOLEAN iiConvert (int inputType, int outputType, int index, leftv input, leftv output)
+{
+  memset(output,0,sizeof(sleftv));
+  if ((inputType==outputType)
+  || (outputType==DEF_CMD)
+  || ((outputType==IDHDL)&&(input->rtyp==IDHDL)))
+  {
+    memcpy(output,input,sizeof(*output));
+    memset(input,0,sizeof(*input));
+    return FALSE;
+  }
+  else if (outputType==ANY_TYPE)
+  {
+    output->rtyp=ANY_TYPE;
+    output->data=(char *)input->Typ();
+    /* the name of the object:*/
+    if (input->e==NULL)
+    {
+      if (input->rtyp==IDHDL)
+      /* preserve name: copy it */
+        output->name=omStrDup(IDID((idhdl)(input->data)));
+      else if (input->name!=NULL)
+      {
+        output->name=input->name;
+        input->name=NULL;
+      }
+      else if ((input->rtyp==POLY_CMD) && (input->name==NULL))
+      {
+        if (input->data!=NULL)
+        {
+          int nr=pIsPurePower((poly)input->data);
+          if (nr!=0)
+          {
+            if (pGetExp((poly)input->data,nr)==1)
+            {
+              output->name=omStrDup(currRing->names[nr-1]);
+            }
+            else
+            {
+              output->name=(char *)omAlloc(4);
+              sprintf(output->name,"%c%d",*(currRing->names[nr-1]),
+              (int)pGetExp((poly)input->data,nr));
+            }
+          }
+          else if(pIsConstant((poly)input->data))
+          {
+            output->name=nName(pGetCoeff((poly)input->data));
+          }
+#ifdef TEST
+          else
+          {
+            WerrorS("wrong name, should not happen");
+            output->name=omStrDup("?");
+          }
+#endif
+        }
+      }
+      else if ((input->rtyp==NUMBER_CMD) && (input->name==NULL))
+      {
+        output->name=nName((number)input->data);
+      }
+      else
+      {
+        /* no need to preserve name: use it */
+        output->name=input->name;
+        memset(input,0,sizeof(*input));
+      }
+    }
+    output->next=input->next;
+    input->next=NULL;
+    return FALSE;
+  }
+  if (index!=0) /* iiTestConvert does not returned 'failure' */
+  {
+    index--;
+
+    if((dConvertTypes[index].i_typ==inputType)
+    &&(dConvertTypes[index].o_typ==outputType))
+    {
+      if ((currRing==NULL) && (outputType>BEGIN_RING) && (outputType<END_RING))
+        return TRUE;
+      output->rtyp=outputType;
+      output->data=dConvertTypes[index].p(input->CopyD());
+      if ((output->data==NULL)
+      && ((outputType==IDEAL_CMD)
+        ||(outputType==MODUL_CMD)
+        ||(outputType==MATRIX_CMD)
+        ||(outputType==INTVEC_CMD)))
+      {
+        return TRUE;
+      }
+      output->next=input->next;
+      input->next=NULL;
+      return FALSE;
+    }
+  }
+  return TRUE;
+}
+
+/*2
+* try to convert 'inputType' in 'outputType'
+* return 0 on failure, an index (<>0) on success
+*/
+int iiTestConvert (int inputType, int outputType)
+{
+  if ((inputType==outputType)
+  || (outputType==DEF_CMD)
+  || (outputType==IDHDL)
+  || (outputType==ANY_TYPE))
+  {
+    return -1;
+  }
+
+  if ((currRing==NULL) && (outputType>BEGIN_RING) && (outputType<END_RING))
+    return 0;
+
+  // search the list
+  int i=0;
+  while (dConvertTypes[i].i_typ!=0)
+  {
+    if((dConvertTypes[i].i_typ==inputType)
+    &&(dConvertTypes[i].o_typ==outputType))
+    {
+      //Print("test convert %d to %d (%s -> %s):%d\n",inputType,outputType,
+      //Tok2Cmdname(inputType), Tok2Cmdname(outputType),i+1);
+      return i+1;
+    }
+    i++;
+  }
+  //Print("test convert %d to %d (%s -> %s):0\n",inputType,outputType,
+  // Tok2Cmdname(inputType), Tok2Cmdname(outputType));
+  return 0;
+}
Index: kernel/ipconv.h
===================================================================
--- kernel/ipconv.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/ipconv.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,16 @@
+#ifndef IPCONVERT_H
+#define IPCONVERT_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: ipconv.h,v 1.1.1.1 2003-10-06 12:15:55 Singular Exp $ */
+/*
+* ABSTRACT: interpreter: converting types
+*/
+#include "structs.h"
+
+int iiTestConvert (int inputType, int outputType);
+BOOLEAN iiConvert (int inputType, int outputType, int index,
+                   leftv input, leftv output);
+#endif
+
Index: kernel/iplib.cc
===================================================================
--- kernel/iplib.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/iplib.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1272 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: iplib.cc,v 1.1.1.1 2003-10-06 12:15:55 Singular Exp $ */
+/*
+* ABSTRACT: interpreter: LIB and help
+*/
+
+//#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/stat.h>
+
+#include "mod2.h"
+#include "static.h"
+#include "tok.h"
+#include "ipid.h"
+#include "omalloc.h"
+#include "febase.h"
+#include "ring.h"
+#include "subexpr.h"
+#include "ipshell.h"
+#include "lists.h"
+
+BOOLEAN load_modules(char *newlib, char *fullname, BOOLEAN tellerror);
+
+#ifdef HAVE_LIBPARSER
+#  include "libparse.h"
+#else /* HAVE_LIBPARSER */
+   procinfo *iiInitSingularProcinfo(procinfov pi, char *libname,
+                                    char *procname, int line, long pos,
+                                    BOOLEAN pstatic = FALSE);
+#endif /* HAVE_LIBPARSER */
+#define NS_LRING (procstack->cRing)
+
+#include "mod_raw.h"
+
+static char *iiConvName(const char *p);
+#ifdef HAVE_LIBPARSER
+void yylprestart (FILE *input_file );
+int current_pos(int i=0);
+extern int yylp_errno;
+extern int yylplineno;
+extern char *yylp_errlist[];
+void print_init();
+libstackv library_stack;
+#endif
+
+//int IsCmd(char *n, int tok);
+char mytolower(char c);
+
+/*2
+* return TRUE if the libray libname is already loaded
+*/
+BOOLEAN iiGetLibStatus(char *lib)
+{
+  idhdl hl;
+
+#ifndef HAVE_NS
+  char *p;
+
+  hl = IDROOT->get("LIB", 0);
+  if (hl == NULL || (p=strstr(IDSTRING(hl), lib)) == NULL) return FALSE;
+  if ((p!=IDSTRING(hl)) && (*(p-1)!=',')) return FALSE;
+
+  return TRUE;
+#else
+  char *plib = iiConvName(lib);
+  hl = basePack->idroot->get(plib,0);
+  if((hl==NULL) ||(IDTYP(hl)!=PACKAGE_CMD))
+  {
+    omFree(plib);
+    return FALSE;
+  }
+  omFree(plib);
+  return (strcmp(lib,IDPACKAGE(hl)->libname)==0);
+#endif
+}
+
+/*2
+* find the library of an proc:
+*  => return (pi->libname)
+*/
+char * iiGetLibName(procinfov pi)
+{
+  return pi->libname;
+}
+
+/*2
+* given a line 'proc[ ]+{name}[ \t]*'
+* return a pointer to name and set the end of '\0'
+* changes the input!
+* returns: e: pointer to 'end of name'
+*          ct: changed char at the end of s
+*/
+char* iiProcName(char *buf, char & ct, char* &e)
+{
+  char *s=buf+5;
+  while (*s==' ') s++;
+  e=s+1;
+  while ((*e>' ') && (*e!='(')) e++;
+  ct=*e;
+  *e='\0';
+  return s;
+}
+
+/*2
+* given a line with args, return the argstr
+*/
+char * iiProcArgs(char *e,BOOLEAN withParenth)
+{
+  while ((*e==' ') || (*e=='\t') || (*e=='(')) e++;
+  if (*e<' ')
+  {
+    if (withParenth)
+    {
+      // no argument list, allow list #
+      return omStrDup("parameter list #;");
+    }
+    else
+    {
+      // empty list
+      return omStrDup("");
+    }
+  }
+  BOOLEAN in_args;
+  BOOLEAN args_found;
+  char *s;
+  char *argstr=(char *)omAlloc(127); // see ../omalloc/omTables.inc
+  int argstrlen=127;
+  *argstr='\0';
+  do
+  {
+    args_found=FALSE;
+    s=e; // set s to the starting point of the arg
+         // and search for the end
+    while ((*e!=',')&&(*e!=')')&&(*e!='\0'))
+    {
+      args_found=args_found || (*e>' ');
+      e++;
+    }
+    in_args=(*e==',');
+    if (args_found)
+    {
+      *e='\0';
+      // check for space:
+      if ((int)strlen(argstr)+12 /* parameter + ;*/ +(int)strlen(s)>= argstrlen)
+      {
+        argstrlen*=2;
+        char *a=(char *)omAlloc( argstrlen);
+        strcpy(a,argstr);
+        omFree((ADDRESS)argstr);
+        argstr=a;
+      }
+      // copy the result to argstr
+      strcat(argstr,"parameter ");
+      strcat(argstr,s);
+      strcat(argstr,"; ");
+      e++; // e was pointing to ','
+    }
+  } while (in_args);
+  return argstr;
+}
+
+/*2
+* locate `procname` in lib `libname` and find the part `part`:
+*  part=0: help, between, but excluding the line "proc ..." and "{...":
+*    => return
+*  part=1: body, between "{ ..." and "}", including the 1. line, w/o "{"
+*    => set pi->data.s.body, return NULL
+*  part=2: example, between, but excluding the line "exapmle {..." and "}":
+*    => return
+*/
+char* iiGetLibProcBuffer(procinfo *pi, int part )
+{
+  char buf[256], *s = NULL, *p;
+  long procbuflen;
+
+  FILE * fp = feFopen( pi->libname, "rb", NULL, TRUE );
+  if (fp==NULL)
+  {
+    return NULL;
+  }
+
+  fseek(fp, pi->data.s.proc_start, SEEK_SET);
+  if(part==0)
+  { // load help string
+    int i, offset=0;
+    long head = pi->data.s.def_end - pi->data.s.proc_start;
+    procbuflen = pi->data.s.help_end - pi->data.s.help_start;
+    if (procbuflen<5)
+      return NULL; // help part does not exist
+    //Print("Help=%ld-%ld=%d\n", pi->data.s.body_start,
+    //    pi->data.s.proc_start, procbuflen);
+    s = (char *)omAlloc(procbuflen+head+3);
+    myfread(s, head, 1, fp);
+    s[head] = '\n';
+    fseek(fp, pi->data.s.help_start, SEEK_SET);
+    myfread(s+head+1, procbuflen, 1, fp);
+    s[procbuflen+head+1] = '\n';
+    s[procbuflen+head+2] = '\0';
+    offset=0;
+    for(i=0;i<=procbuflen+head+2; i++)
+    {
+      if(s[i]=='\\' &&
+         (s[i+1]=='"' || s[i+1]=='{' || s[i+1]=='}' || s[i+1]=='\\'))
+      {
+        i++;
+        offset++;
+      }
+      if(offset>0) s[i-offset] = s[i];
+    }
+    return(s);
+  }
+  else if(part==1)
+  { // load proc part - must exist
+    procbuflen = pi->data.s.def_end - pi->data.s.proc_start;
+    char *ss=(char *)omAlloc(procbuflen+2);
+    //fgets(buf, sizeof(buf), fp);
+    myfread( ss, procbuflen, 1, fp);
+    char ct;
+    char *e;
+    s=iiProcName(ss,ct,e);
+    char *argstr=NULL;
+    *e=ct;
+    argstr=iiProcArgs(e,TRUE);
+
+    assume(pi->data.s.body_end > pi->data.s.body_start);
+
+    procbuflen = pi->data.s.body_end - pi->data.s.body_start;
+    pi->data.s.body = (char *)omAlloc( strlen(argstr)+procbuflen+15+
+                                      strlen(pi->libname) );
+    //Print("Body=%ld-%ld=%d\n", pi->data.s.body_end,
+    //    pi->data.s.body_start, procbuflen);
+    assume(pi->data.s.body != NULL);
+    fseek(fp, pi->data.s.body_start, SEEK_SET);
+    strcpy(pi->data.s.body,argstr);
+    myfread( pi->data.s.body+strlen(argstr), procbuflen, 1, fp);
+    procbuflen+=strlen(argstr);
+    omFree(argstr);
+    omFree(ss);
+    fclose( fp );
+    pi->data.s.body[procbuflen] = '\0';
+    strcat( pi->data.s.body+procbuflen, "\n;return();\n\n" );
+    strcat( pi->data.s.body+procbuflen+13,pi->libname);
+    s=strchr(pi->data.s.body,'{');
+    if (s!=NULL) *s=' ';
+    return NULL;
+  }
+  else if(part==2)
+  { // example
+    if ( pi->data.s.example_lineno == 0)
+      return NULL; // example part does not exist
+    // load example
+    fseek(fp, pi->data.s.example_start, SEEK_SET);
+    fgets(buf, sizeof(buf), fp); // skip line with "example"
+    procbuflen = pi->data.s.proc_end - pi->data.s.example_start - strlen(buf);
+    //Print("Example=%ld-%ld=%d\n", pi->data.s.proc_end,
+    //  pi->data.s.example_start, procbuflen);
+    s = (char *)omAlloc(procbuflen+14);
+    myfread(s, procbuflen, 1, fp);
+    s[procbuflen] = '\0';
+    strcat(s+procbuflen-3, "\n;return();\n\n" );
+    p=strchr(s,'{');
+    if (p!=NULL) *p=' ';
+    return(s);
+  }
+  return NULL;
+}
+
+/*2
+* start a proc
+* parameters are built as exprlist
+* TODO:interrupt
+* return FALSE on success, TRUE if an error occurs
+*/
+BOOLEAN iiPStart(idhdl pn, sleftv  * v)
+{
+  char * str;
+  BOOLEAN err=FALSE;
+  int old_echo=si_echo;
+  char save_flags=0;
+  procinfov pi=NULL;
+
+  /* init febase ======================================== */
+  /* we do not enter this case if filename != NULL !! */
+  if (pn!=NULL)
+  {
+    pi = IDPROC(pn);
+    if(pi!=NULL)
+    {
+      save_flags=pi->trace_flag;
+      if( pi->data.s.body==NULL )
+      {
+        iiGetLibProcBuffer(pi);
+        if (pi->data.s.body==NULL) return TRUE;
+      }
+      newBuffer( omStrDup(pi->data.s.body), BT_proc,
+                 pi, pi->data.s.body_lineno-(v!=NULL) );
+    }
+  }
+  /* generate argument list ======================================*/
+  if (v!=NULL)
+  {
+    iiCurrArgs=(leftv)omAllocBin(sleftv_bin);
+    memcpy(iiCurrArgs,v,sizeof(sleftv));
+    memset(v,0,sizeof(sleftv));
+  }
+  else
+  {
+    iiCurrArgs=NULL;
+  }
+  /* start interpreter ======================================*/
+  myynest++;
+  err=yyparse();
+#ifdef HAVE_NS
+  checkall();
+#endif
+  if (sLastPrinted.rtyp!=0)
+  {
+    sLastPrinted.CleanUp();
+  }
+  //Print("kill locals for %s (level %d)\n",IDID(pn),myynest);
+  killlocals(myynest);
+#ifdef HAVE_NS
+  checkall();
+#endif
+  //Print("end kill locals for %s (%d)\n",IDID(pn),myynest);
+  myynest--;
+  si_echo=old_echo;
+  if (pi!=NULL)
+    pi->trace_flag=save_flags;
+  return err;
+}
+
+#ifdef USE_IILOCALRING
+ring    *iiLocalRing;
+#endif
+sleftv  *iiRETURNEXPR;
+int     iiRETURNEXPR_len=0;
+
+#ifdef RDEBUG
+static void iiShowLevRings()
+{
+  int i;
+#ifdef USE_IILOCALRING
+  for (i=1;i<=myynest;i++)
+  {
+    Print("lev %d:",i);
+    if (iiLocalRing[i]==NULL) PrintS("NULL");
+    else                      Print("%d",iiLocalRing[i]);
+    PrintLn();
+  }
+#endif
+#if  0
+//#ifdef HAVE_NS
+  i=myynest;
+  proclevel *p=procstack;
+  while (p!=NULL)
+  {
+    Print("lev %d:",i);
+    if (p->cRingHdl==NULL) PrintS("NULL");
+    else                   Print("%s",IDID(p->cRingHdl));
+    PrintLn();
+    p=p->next;
+  }
+#endif
+  if (currRing==NULL) PrintS("curr:NULL\n");
+  else                Print ("curr:%x\n",currRing);
+}
+#endif /* RDEBUG */
+
+static void iiCheckNest()
+{
+  if (myynest >= iiRETURNEXPR_len-1)
+  {
+    iiRETURNEXPR=(sleftv *)omreallocSize(iiRETURNEXPR,
+                                   iiRETURNEXPR_len*sizeof(sleftv),
+                                   (iiRETURNEXPR_len+16)*sizeof(sleftv));
+    omMarkAsStaticAddr(iiRETURNEXPR);
+    memset(&(iiRETURNEXPR[iiRETURNEXPR_len]),0,16*sizeof(sleftv));
+#ifdef USE_IILOCALRING
+    iiLocalRing=(ring *)omreallocSize(iiLocalRing,
+                                   iiRETURNEXPR_len*sizeof(ring),
+                                   (iiRETURNEXPR_len+16)*sizeof(ring));
+    memset(&(iiLocalRing[iiRETURNEXPR_len]),0,16*sizeof(ring));
+#endif
+    iiRETURNEXPR_len+=16;
+  }
+}
+#ifdef HAVE_NS
+sleftv * iiMake_proc(idhdl pn, package pack, sleftv* sl)
+#else /* HAVE_NS */
+sleftv * iiMake_proc(idhdl pn, sleftv* sl)
+#endif /* HAVE_NS */
+{
+  int err;
+  procinfov pi = IDPROC(pn);
+  char *plib = iiConvName(pi->libname);
+  omFree((ADDRESS)plib);
+  if(pi->is_static && myynest==0)
+  {
+    Werror("'%s::%s()' is a local procedure and cannot be accessed by an user.",
+           pi->libname, pi->procname);
+    return NULL;
+  }
+  iiCheckNest();
+#ifdef USE_IILOCALRING
+  iiLocalRing[myynest]=currRing;
+#endif
+  iiRETURNEXPR[myynest+1].Init();
+  procstack->push(pi->procname);
+  if ((traceit&TRACE_SHOW_PROC)
+  || (pi->trace_flag&TRACE_SHOW_PROC))
+  {
+    if (traceit&TRACE_SHOW_LINENO) PrintLn();
+    Print("entering%-*.*s %s (level %d)\n",myynest*2,myynest*2," ",IDID(pn),myynest);
+  }
+#ifdef RDEBUG
+  if (traceit&TRACE_SHOW_RINGS) iiShowLevRings();
+#endif
+  switch (pi->language)
+  {
+      default:
+      case LANG_NONE:
+                 err=TRUE;
+                 break;
+
+    case LANG_SINGULAR:
+                 #ifdef HAVE_NS
+                 if ((pi->pack!=NULL)&&(currPack!=pi->pack))
+                 {
+                   currPack=pi->pack;
+                   iiCheckPack(currPack);
+                   currPackHdl=packFindHdl(currPack);
+                   //Print("set pack=%s\n",IDID(currPackHdl));
+                 }
+                 else if ((pack!=NULL)&&(currPack!=pack))
+                 {
+                   currPack=pack;
+                   iiCheckPack(currPack);
+                   currPackHdl=packFindHdl(currPack);
+                   //Print("set pack=%s\n",IDID(currPackHdl));
+                 }
+                 #endif
+                 err=iiPStart(pn,sl);
+                 #ifdef HAVE_NS
+                 #endif
+                 break;
+    case LANG_C:
+                 leftv res = (leftv)omAlloc0Bin(sleftv_bin);
+                 err = (pi->data.o.function)(res, sl);
+                 iiRETURNEXPR[myynest+1].Copy(res);
+                 omFreeBin((ADDRESS)res,  sleftv_bin);
+                 break;
+  }
+  if ((traceit&TRACE_SHOW_PROC)
+  || (pi->trace_flag&TRACE_SHOW_PROC))
+  {
+    if (traceit&TRACE_SHOW_LINENO) PrintLn();
+    Print("leaving %-*.*s %s (level %d)\n",myynest*2,myynest*2," ",IDID(pn),myynest);
+  }
+#ifdef RDEBUG
+  if (traceit&TRACE_SHOW_RINGS) iiShowLevRings();
+#endif
+  if (err)
+  {
+    iiRETURNEXPR[myynest+1].CleanUp();
+    //iiRETURNEXPR[myynest+1].Init(); //done by CleanUp
+  }
+#ifdef USE_IILOCALRING
+#if 0
+  if(procstack->cRing != iiLocalRing[myynest]) Print("iiMake_proc: 1 ring not saved procs:%x, iiLocal:%x\n",procstack->cRing, iiLocalRing[myynest]);
+#endif
+  if (iiLocalRing[myynest] != currRing)
+  {
+    if (((iiRETURNEXPR[myynest+1].Typ()>BEGIN_RING)
+      && (iiRETURNEXPR[myynest+1].Typ()<END_RING))
+    || ((iiRETURNEXPR[myynest+1].Typ()==LIST_CMD)
+      && (lRingDependend((lists)iiRETURNEXPR[myynest+1].Data()))))
+    {
+      //idhdl hn;
+      char *n;
+      char *o;
+      if (iiLocalRing[myynest]!=NULL) o=rFindHdl(iiLocalRing[myynest],NULL, NULL)->id;
+      else                            o="none";
+      if (currRing!=NULL)             n=rFindHdl(currRing,NULL, NULL)->id;
+      else                            n="none";
+      Werror("ring change during procedure call: %s -> %s",o,n);
+      iiRETURNEXPR[myynest+1].CleanUp();
+      err=TRUE;
+    }
+    currRing=iiLocalRing[myynest];
+  }
+  if ((currRing!=NULL) &&
+    ((currRingHdl==NULL)||(IDRING(currRingHdl)!=currRing)
+     ||(IDLEV(currRingHdl)>=myynest)))
+  {
+    rSetHdl(rFindHdl(currRing,NULL, NULL));
+    iiLocalRing[myynest]=NULL;
+  }
+#else /* USE_IILOCALRING */
+  if (procstack->cRing != currRing)
+  {
+    //if (procstack->cRingHdl!=NULL)
+    //Print("procstack:%s,",IDID(procstack->cRingHdl));
+    //if (currRingHdl!=NULL)
+    //Print(" curr:%s\n",IDID(currRingHdl));
+    //Print("pr:%x, curr: %x\n",procstack->cRing,currRing);
+    if (((iiRETURNEXPR[myynest+1].Typ()>BEGIN_RING)
+      && (iiRETURNEXPR[myynest+1].Typ()<END_RING))
+    || ((iiRETURNEXPR[myynest+1].Typ()==LIST_CMD)
+      && (lRingDependend((lists)iiRETURNEXPR[myynest+1].Data()))))
+    {
+      //idhdl hn;
+      char *n;
+      char *o;
+      if (procstack->cRing!=NULL)
+      {
+        //PrintS("reset ring\n");
+        procstack->cRingHdl=rFindHdl(procstack->cRing,NULL, NULL);
+        #ifdef HAVE_NS
+        if (procstack->cRingHdl==NULL)
+          procstack->cRingHdl=
+           rFindHdl(procstack->cRing,NULL,procstack->currPack->idroot);
+        if (procstack->cRingHdl==NULL)
+          procstack->cRingHdl=
+           rFindHdl(procstack->cRing,NULL,basePack->idroot);
+        #endif
+        o=IDID(procstack->cRingHdl);
+        currRing=procstack->cRing;
+        currRingHdl=procstack->cRingHdl;
+      }
+      else                            o="none";
+      if (currRing!=NULL)             n=IDID(currRingHdl);
+      else                            n="none";
+      if (currRing==NULL)
+      {
+        Werror("ring change during procedure call: %s -> %s",o,n);
+        iiRETURNEXPR[myynest+1].CleanUp();
+        err=TRUE;
+      }
+    }
+    if (procstack->cRingHdl!=NULL)
+    {
+      rSetHdl(procstack->cRingHdl);
+    }
+    else
+    { currRingHdl=NULL; currRing=NULL; }
+  }
+#endif /* USE_IILOCALRING */
+  if (iiCurrArgs!=NULL)
+  {
+    if (!err) Warn("too many arguments for %s",IDID(pn));
+    iiCurrArgs->CleanUp();
+    omFreeBin((ADDRESS)iiCurrArgs, sleftv_bin);
+    iiCurrArgs=NULL;
+  }
+  procstack->pop();
+  if (err)
+    return NULL;
+  return &iiRETURNEXPR[myynest+1];
+}
+
+/*2
+* start an example (as a proc),
+* destroys the string 'example'
+*/
+BOOLEAN iiEStart(char* example, procinfo *pi)
+{
+  BOOLEAN err;
+  int old_echo=si_echo;
+
+  newBuffer( example, BT_example, pi,
+             (pi != NULL ? pi->data.s.example_lineno: 0));
+
+  iiCheckNest();
+  procstack->push(example);
+#ifdef USE_IILOCALRING
+  iiLocalRing[myynest]=currRing;
+#endif
+  if (traceit&TRACE_SHOW_PROC)
+  {
+    if (traceit&TRACE_SHOW_LINENO) printf("\n");
+    printf("entering example (level %d)\n",myynest);
+  }
+  myynest++;
+  err=yyparse();
+  if (sLastPrinted.rtyp!=0)
+  {
+    sLastPrinted.CleanUp();
+    //memset(&sLastPrinted,0,sizeof(sleftv)); //done by CleanUp
+  }
+  killlocals(myynest);
+  myynest--;
+  si_echo=old_echo;
+  if (traceit&TRACE_SHOW_PROC)
+  {
+    if (traceit&TRACE_SHOW_LINENO) printf("\n");
+    printf("leaving  -example- (level %d)\n",myynest);
+  }
+#ifdef USE_IILOCALRING
+  if (iiLocalRing[myynest] != currRing)
+  {
+    if (iiLocalRing[myynest]!=NULL)
+    {
+      rSetHdl(rFindHdl(iiLocalRing[myynest],NULL, NULL));
+      iiLocalRing[myynest]=NULL;
+    }
+    else
+    {
+      currRingHdl=NULL;
+      currRing=NULL;
+    }
+  }
+#else /* USE_IILOCALRING */
+#endif /* USE_IILOCALRING */
+  if (NS_LRING != currRing)
+  {
+    if (NS_LRING!=NULL)
+    {
+      idhdl rh=procstack->cRingHdl;
+      if ((rh==NULL)||(IDRING(rh)!=NS_LRING))
+        rh=rFindHdl(NS_LRING,NULL, NULL);
+      rSetHdl(rh);
+    }
+    else
+    {
+      currRingHdl=NULL;
+      currRing=NULL;
+    }
+  }
+//#endif /* USE_IILOCALRING */
+  procstack->pop();
+  return err;
+}
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+static BOOLEAN iiLoadLIB(FILE *fp, char *libnamebuf, char *newlib,
+                         idhdl pl, BOOLEAN autoexport, BOOLEAN tellerror);
+
+BOOLEAN iiTryLoadLib(leftv v, char *id)
+{
+  BOOLEAN LoadResult = TRUE;
+#ifdef HAVE_NAMESPACES
+  char libnamebuf[128];
+  char *libname = (char *)omAlloc(strlen(id)+5);
+  char *suffix[] = { "", ".lib", ".so", ".sl", NULL };
+  int i = 0;
+  FILE *fp;
+  package pack;
+  idhdl packhdl;
+  lib_types LT;
+
+  for(i=0; suffix[i] != NULL; i++)
+  {
+    sprintf(libname, "%s%s", id, suffix[i]);
+    *libname = mytolower(*libname);
+    if((LT = type_of_LIB(libname, libnamebuf)) > LT_NOTFOUND)
+    {
+      char *s=omStrDup(libname);
+      char libnamebuf[256];
+
+      if (LT==LT_SINGULAR)
+        LoadResult = iiLibCmd(s, FALSE);
+      else if ((LT==LT_ELF) || (LT==LT_HPUX))
+        LoadResult = load_modules(s,libnamebuf,FALSE);
+      if(!LoadResult )
+      {
+        v->name = iiConvName(libname);
+        break;
+      }
+    }
+  }
+  omFree(libname);
+#else /* HAVE_NAMESPACES */
+#endif /* HAVE_NAMESPACES */
+  return LoadResult;
+}
+
+BOOLEAN iiReLoadLib(idhdl packhdl)
+{
+  BOOLEAN LoadResult = TRUE;
+#ifdef HAVE_NAMESPACES
+  char libnamebuf[128];
+  package pack = IDPACKAGE(packhdl);
+
+  if(pack->language == LANG_NONE) return FALSE;
+
+  FILE * fp = feFopen( pack->libname, "r", libnamebuf, FALSE);
+  if (fp==NULL)
+  {
+    return TRUE;
+  }
+  namespaceroot->push(IDPACKAGE(packhdl), IDID(packhdl));
+  LoadResult = iiLoadLIB(fp, libnamebuf, IDPACKAGE(packhdl)->libname,
+                         packhdl, FALSE, FALSE);
+  namespaceroot->pop();
+#else /* HAVE_NAMESPACES */
+#endif /* HAVE_NAMESPACES */
+  return LoadResult;
+}
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+/* check, if library lib has already been loaded
+   if yes, writes filename of lib into where and returns TRUE,
+      no, returns FALSE
+*/
+BOOLEAN iiLocateLib(const char* lib, char* where)
+{
+  idhdl hl;
+
+  char *p;
+
+  hl = IDROOT->get("LIB", 0);
+  if (hl == NULL || (p=strstr(IDSTRING(hl), lib)) == NULL) return FALSE;
+  if ((p!=IDSTRING(hl)) && (*(p-1)!=',')) return FALSE;
+
+  if (strstr(IDSTRING(hl), ",") == NULL)
+  {
+    strcpy(where, IDSTRING(hl));
+  }
+  else
+  {
+    char* tmp = omStrDup(IDSTRING(hl));
+    char* tok = strtok(tmp, ",");
+    do
+    {
+      if (strstr(tok, lib) != NULL) break;
+      tok = strtok(NULL, ",");
+    }
+    while (tok != NULL);
+    assume(tok != NULL);
+    strcpy(where, tok);
+    omFree(tmp);
+  }
+  return TRUE;
+}
+
+BOOLEAN iiLibCmd( char *newlib, BOOLEAN tellerror )
+{
+  char buf[256];
+  char libnamebuf[128];
+  idhdl h;
+  BOOLEAN LoadResult = TRUE;
+#ifdef HAVE_NS
+  idhdl pl;
+#endif
+  idhdl hl;
+  int lines = 1;
+  long pos = 0L;
+  procinfov pi;
+#ifdef HAVE_NS
+  char *plib = iiConvName(newlib);
+#endif
+  FILE * fp = feFopen( newlib, "r", libnamebuf, tellerror );
+  if (fp==NULL)
+  {
+    return TRUE;
+  }
+#ifndef HAVE_NS
+  hl = idroot->get("LIB",0);
+  if (hl==NULL)
+  {
+    hl = enterid( "LIB",0, STRING_CMD, &idroot, FALSE );
+    IDSTRING(hl) = omStrDup(newlib);
+  }
+  else
+  {
+#ifdef TEST
+    if (IDSTRING(hl) != NULL)
+#endif
+    {
+      char *s = (char *)omAlloc( strlen(newlib) + strlen(IDSTRING(hl)) + 2 );
+      strcpy(s,IDSTRING(hl));
+      BOOLEAN f=FALSE;
+      if(strchr(s,',')==NULL)
+      {
+        if (strcmp(s,newlib)==0)
+          f=TRUE;
+      }
+      else
+      {
+        char *p=strtok(s,",");
+        do
+        {
+          if(strcmp(p,newlib)==0)
+          {
+            f=TRUE;
+            break;
+          }
+          p=strtok(NULL,",");
+        } while (p!=NULL);
+      }
+      if (f)
+        omFree((ADDRESS)s);
+      else
+      {
+        sprintf( s, "%s,%s", IDSTRING(hl), newlib);
+        omFree((ADDRESS)IDSTRING(hl));
+        IDSTRING(hl) = s;
+      }
+    }
+#ifdef TEST
+    else
+    {
+      PrintS("## empty LIB string\n");
+      IDSTRING(hl) = omStrDup(newlib);
+    }
+#endif
+  }
+#endif /* HAVE_NS */
+#ifdef HAVE_TCL
+  if (tclmode)
+  {
+    PrintTCLS('L',newlib);
+  }
+#endif
+#ifdef HAVE_NS
+  pl = basePack->idroot->get(plib,0);
+  if (pl==NULL)
+  {
+    pl = enterid( plib,0, PACKAGE_CMD,
+                  &(basePack->idroot), TRUE );
+    IDPACKAGE(pl)->language = LANG_SINGULAR;
+    IDPACKAGE(pl)->libname=omStrDup(newlib);
+  }
+  else
+  {
+    if(IDTYP(pl)!=PACKAGE_CMD)
+    {
+      WarnS("not of typ package.");
+      fclose(fp);
+      return TRUE;
+    }
+  }
+  LoadResult = iiLoadLIB(fp, libnamebuf, newlib, pl, TRUE, tellerror);
+#else /* HAVE_NS */
+  LoadResult = iiLoadLIB(fp, libnamebuf, newlib, NULL, FALSE, tellerror);
+#endif /* HAVE_NS */
+
+  omFree((ADDRESS)newlib);
+
+#ifdef HAVE_NS
+  if(!LoadResult) IDPACKAGE(pl)->loaded = TRUE;
+  omFree((ADDRESS)plib);
+#endif /* HAVE_NS */
+
+ return LoadResult;
+}
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+static void iiCleanProcs(idhdl &root)
+{
+  idhdl prev=NULL;
+  loop
+  {
+    if (root==NULL) return;
+    if (IDTYP(root)==PROC_CMD)
+    {
+      procinfo *pi=(procinfo*)IDDATA(root);
+      if ((pi->language == LANG_SINGULAR)
+      && (pi->data.s.body_start == 0L))
+      {
+        // procinfo data incorrect:
+        // - no proc body can start at the beginning of the file
+        killhdl(root);
+        if (prev==NULL)
+          root=IDROOT;
+        else
+        {
+          root=prev;
+          prev=NULL;
+        }
+        continue;
+      }
+    }
+    prev=root;
+    root=IDNEXT(root);
+  }
+}
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+static BOOLEAN iiLoadLIB(FILE *fp, char *libnamebuf, char*newlib,
+             idhdl pl, BOOLEAN autoexport, BOOLEAN tellerror)
+{
+  char buf[256];
+  extern FILE *yylpin;
+  libstackv ls_start = library_stack;
+  lib_style_types lib_style;
+
+  yylpin = fp;
+  #if YYLPDEBUG > 1
+  print_init();
+  #endif
+  extern int lpverbose;
+  if (BVERBOSE(V_DEBUG_LIB)) lpverbose=1;
+  else lpverbose=0;
+  #ifdef HAVE_NS
+    yylplex(newlib, libnamebuf, &lib_style, pl, autoexport);
+  #else
+    yylplex(newlib, libnamebuf, &lib_style);
+  #endif /* HAVE_NS */
+  if(yylp_errno)
+  {
+    Werror("Library %s: ERROR occured: in line %d, %d.", newlib, yylplineno,
+         current_pos(0));
+    if(yylp_errno==YYLP_BAD_CHAR)
+    {
+      Werror(yylp_errlist[yylp_errno], *text_buffer, yylplineno);
+      omFree((ADDRESS)text_buffer);
+      text_buffer=NULL;
+    }
+    else
+      Werror(yylp_errlist[yylp_errno], yylplineno);
+    Werror("Cannot load library,... aborting.");
+    reinit_yylp();
+    fclose( yylpin );
+    iiCleanProcs(IDROOT);
+    return TRUE;
+  }
+  if (BVERBOSE(V_LOAD_LIB))
+    Print( "// ** loaded %s %s\n", libnamebuf, text_buffer);
+  if( (lib_style == OLD_LIBSTYLE) && (BVERBOSE(V_LOAD_LIB)))
+  {
+    Warn( "library %s has old format. This format is still accepted,", newlib);
+    Warn( "but for functionality you may wish to change to the new");
+    Warn( "format. Please refer to the manual for further information.");
+  }
+  reinit_yylp();
+  fclose( yylpin );
+  fp = NULL;
+
+  {
+    libstackv ls;
+    for(ls = library_stack; (ls != NULL) && (ls != ls_start); )
+    {
+      if(ls->to_be_done)
+      {
+        ls->to_be_done=FALSE;
+        iiLibCmd(ls->get());
+        ls = ls->pop(newlib);
+      }
+    }
+#if 0
+    PrintS("--------------------\n");
+    for(ls = library_stack; ls != NULL; ls = ls->next)
+    {
+      Print("%s: LIB-stack:(%d), %s %s\n", newlib, ls->cnt, ls->get(),
+        ls->to_be_done ? "not loaded" : "loaded");
+    }
+    PrintS("--------------------\n");
+#endif
+  }
+
+  if(fp != NULL) fclose(fp);
+  return FALSE;
+}
+
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+procinfo *iiInitSingularProcinfo(procinfov pi, char *libname, char *procname,
+                                 int line, long pos, BOOLEAN pstatic)
+{
+  pi->libname = omStrDup(libname);
+
+  if( strcmp(procname,"_init")==0)
+  {
+    pi->procname = iiConvName(libname);
+  }
+  else
+    pi->procname = omStrDup(procname);
+  pi->language = LANG_SINGULAR;
+  pi->ref = 1;
+#ifdef HAVE_NS
+  pi->pack = NULL;
+#endif
+  pi->is_static = pstatic;
+  pi->data.s.proc_start = pos;
+  pi->data.s.def_end    = 0L;
+  pi->data.s.help_start = 0L;
+  pi->data.s.help_end   = 0L;
+  pi->data.s.body_start = 0L;
+  pi->data.s.body_end   = 0L;
+  pi->data.s.example_start = 0L;
+  pi->data.s.proc_lineno = line;
+  pi->data.s.body_lineno = 0;
+  pi->data.s.example_lineno = 0;
+  pi->data.s.body = NULL;
+  pi->data.s.help_chksum = 0;
+  return(pi);
+}
+
+#ifdef HAVE_DYNAMIC_LOADING
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+int iiAddCproc(char *libname, char *procname, BOOLEAN pstatic,
+               BOOLEAN(*func)(leftv res, leftv v))
+{
+  procinfov pi;
+  idhdl h;
+
+  h = enterid(procname,0, PROC_CMD, &IDROOT, TRUE);
+  if ( h!= NULL )
+  {
+    pi = IDPROC(h);
+    pi->libname = omStrDup(libname);
+    pi->procname = omStrDup(procname);
+    pi->language = LANG_C;
+    pi->ref = 1;
+    pi->is_static = pstatic;
+    pi->data.o.function = func;
+    return(1);
+  }
+  else
+  {
+    PrintS("iiAddCproc: failed.\n");
+  }
+  return(0);
+}
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+BOOLEAN load_modules(char *newlib, char *fullname, BOOLEAN tellerror)
+{
+#ifdef HAVE_STATIC
+  WerrorS("mod_init: static version can not load modules");
+  return TRUE;
+#else
+  int iiAddCproc(char *libname, char *procname, BOOLEAN pstatic,
+                 BOOLEAN(*func)(leftv res, leftv v));
+  typedef int (*fktn_t)(int(*iiAddCproc)(char *libname, char *procname,
+                               BOOLEAN pstatic,
+                               BOOLEAN(*func)(leftv res, leftv v)));
+  fktn_t fktn;
+  idhdl pl;
+  char *plib = iiConvName(newlib);
+  BOOLEAN RET=TRUE;
+  int token;
+  char FullName[256];
+
+  memset(FullName,0,256);
+
+  if( *fullname != '/' &&  *fullname != '.' )
+    sprintf(FullName, "./%s", newlib);
+  else strncpy(FullName, fullname,255);
+
+
+  if(IsCmd(plib, token))
+  {
+    Werror("'%s' is resered identifier\n", plib);
+    goto load_modules_end;
+  }
+  pl = IDROOT->get(plib,0);
+  if (pl==NULL)
+  {
+    pl = enterid( plib,0, PACKAGE_CMD, &IDROOT,
+                  TRUE );
+    IDPACKAGE(pl)->language = LANG_C;
+    IDPACKAGE(pl)->libname=omStrDup(newlib);
+  }
+  else
+  {
+    if(IDTYP(pl)!=PACKAGE_CMD)
+    {
+      Warn("not of typ package.");
+      goto load_modules_end;
+    }
+  }
+  if((IDPACKAGE(pl)->handle=dynl_open(FullName))==(void *)NULL)
+  {
+    Werror("dynl_open failed:%s", dynl_error());
+    Werror("%s not found", newlib);
+    goto load_modules_end;
+  }
+  else
+  {
+#ifdef HAVE_NS
+    package s=currPack;
+    currPack=IDPACKAGE(pl);
+#endif
+    fktn = (fktn_t)dynl_sym(IDPACKAGE(pl)->handle, "mod_init");
+    if( fktn!= NULL) (*fktn)(iiAddCproc);
+    else Werror("mod_init: %s\n", dynl_error());
+    if (BVERBOSE(V_LOAD_LIB)) Print( "// ** loaded %s \n", fullname);
+#ifdef HAVE_NS
+    currPack->loaded=1;
+    currPack=s;
+#endif
+  }
+  RET=FALSE;
+
+  load_modules_end:
+  return RET;
+#endif /*STATIC */  
+}
+#endif /* HAVE_DYNAMIC_LOADING */
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+char mytoupper(char c)
+{
+  if(c>=97 && c<=(97+26)) c-=32;
+  return(c);
+}
+
+char mytolower(char c)
+{
+  if(c>=65 && c<=(65+26)) c+=32;
+  return(c);
+}
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+//#if defined(WINNT)
+//#  define  FS_SEP '\\'
+//#elif defined(macintosh)
+//#  define FS_SEP ','
+//#else
+//#  define FS_SEP '/'
+//#endif
+
+static char *iiConvName(const char *libname)
+{
+  char *tmpname = omStrDup(libname);
+  char *p = strrchr(tmpname, DIR_SEP);
+  char *r;
+  if(p==NULL) p = tmpname;
+  else p++;
+  r = strchr(p, '.');
+  if( r!= NULL) *r = '\0';
+  r = omStrDup(p);
+  *r = mytoupper(*r);
+  // printf("iiConvName: '%s' '%s' => '%s'\n", libname, tmpname, r);
+  omFree((ADDRESS)tmpname);
+
+  return(r);
+}
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+void piShowProcList()
+{
+  idhdl h;
+  procinfo *proc;
+  char *name;
+
+  Print( "%-15s  %20s      %s,%s  %s,%s   %s,%s\n", "Library", "function",
+         "line", "start", "line", "body", "line", "example");
+  for(h = IDROOT; h != NULL; h = IDNEXT(h))
+  {
+    if(IDTYP(h) == PROC_CMD)
+    {
+      proc = IDPROC(h);
+      if(strcmp(proc->procname, IDID(h))!=0)
+      {
+        name = (char *)omAlloc(strlen(IDID(h))+strlen(proc->procname)+4);
+        sprintf(name, "%s -> %s", IDID(h), proc->procname);
+        Print( "%d %-15s  %20s ", proc->is_static ? 1 : 0, proc->libname, name);
+        omFree((ADDRESS)name);
+      }
+      else
+        Print( "%d %-15s  %20s ", proc->is_static ? 1 : 0, proc->libname,
+               proc->procname);
+      if(proc->language==LANG_SINGULAR)
+        Print("line %4d,%-5ld  %4d,%-5ld  %4d,%-5ld\n",
+              proc->data.s.proc_lineno, proc->data.s.proc_start,
+              proc->data.s.body_lineno, proc->data.s.body_start,
+              proc->data.s.example_lineno, proc->data.s.example_start);
+      else if(proc->language==LANG_C)
+        Print("type: object\n");
+    }
+  }
+}
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+//char *iiLineNo(char *procname, int lineno)
+//{
+//  char buf[256];
+//  idhdl pn = ggetid(procname);
+//  procinfo *pi = IDPROC(pn);
+//
+//  sprintf(buf, "%s %3d\0", procname, lineno);
+//  //sprintf(buf, "%s::%s %3d\0", pi->libname, pi->procname,
+//  //  lineno + pi->data.s.body_lineno);
+//  return(buf);
+//}
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#ifdef HAVE_LIBPARSER
+void libstack::push(char *p, char *libname)
+{
+  libstackv lp;
+  if( !iiGetLibStatus(libname))
+  {
+    for(lp = this;lp!=NULL;lp=lp->next)
+    {
+      if(strcmp(lp->get(), libname)==0) break;
+    }
+    if(lp==NULL)
+    {
+      libstackv ls = (libstack *)omAlloc0Bin(libstack_bin);
+      ls->next = this;
+      ls->libname = omStrDup(libname);
+      ls->to_be_done = TRUE;
+      if(this != NULL) ls->cnt = this->cnt+1; else ls->cnt = 0;
+      library_stack = ls;
+    }
+  }
+}
+
+libstackv libstack::pop(char *p)
+{
+  libstackv ls = this;
+  //omFree((ADDRESS)ls->libname);
+  library_stack = ls->next;
+  omFreeBin((ADDRESS)ls,  libstack_bin);
+  return(library_stack);
+}
+
+#endif /* HAVE_LIBPARSER */
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#ifndef HOWMANY
+# define HOWMANY 8192           /* how much of the file to look at */
+#endif
+
+lib_types type_of_LIB(char *newlib, char *libnamebuf)
+{
+  char        buf[HOWMANY+1];        /* one extra for terminating '\0' */
+  struct stat sb;
+  int nbytes = 0;
+  int ret;
+  lib_types LT=LT_NONE;
+
+  FILE * fp = feFopen( newlib, "r", libnamebuf, FALSE );
+  ret = stat(libnamebuf, &sb);
+
+  if (fp==NULL)
+  {
+    return LT_NOTFOUND;
+  }
+  if((sb.st_mode & S_IFMT) != S_IFREG)
+  {
+    goto lib_type_end;
+  }
+  if ((nbytes = fread((char *)buf, sizeof(char), HOWMANY, fp)) == -1)
+  {
+    goto lib_type_end;
+    /*NOTREACHED*/
+  }
+  if (nbytes == 0)
+    goto lib_type_end;
+  else
+  {
+    buf[nbytes++] = '\0';        /* null-terminate it */
+  }
+  if( (strncmp(buf, "\177ELF\01\01\01", 7)==0) && buf[16]=='\03')
+  {
+    LT = LT_ELF;
+    //omFree(newlib);
+    //newlib = omStrDup(libnamebuf);
+    goto lib_type_end;
+  }
+  if( (strncmp(buf, "\02\020\01\016\05\022@", 7)==0))
+  {
+    LT = LT_HPUX;
+    //omFree(newlib);
+    //newlib = omStrDup(libnamebuf);
+    goto lib_type_end;
+  }
+  if(isprint(buf[0]) || buf[0]=='\n')
+  { LT = LT_SINGULAR; goto lib_type_end; }
+
+  lib_type_end:
+  fclose(fp);
+  return LT;
+}
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
Index: kernel/kInline.cc
===================================================================
--- kernel/kInline.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/kInline.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1017 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    kInline.cc
+ *  Purpose: implementation of std related inline routines
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: kInline.cc,v 1.1.1.1 2003-10-06 12:15:56 Singular Exp $
+ *******************************************************************/
+#ifndef KINLINE_CC
+#define KINLINE_CC
+
+#if !defined(NO_KINLINE) || defined(KUTIL_CC)
+
+#include "p_polys.h"
+#include "p_Procs.h"
+#include "kbuckets.h"
+#include "omalloc.h"
+
+#define HAVE_TAIL_BIN
+// This doesn't really work, fixme, if necessary
+// #define HAVE_LM_BIN
+
+
+KINLINE TObject* skStrategy::S_2_T(int i)
+{
+  assume(i>= 0 && i<=sl);
+  assume(S_2_R[i] >= 0 && S_2_R[i] <= tl);
+  TObject* T = R[S_2_R[i]];
+  assume(T != NULL && T->p == S[i]);
+  return T;
+}
+
+KINLINE TObject* skStrategy::s_2_t(int i)
+{
+  if (i >= 0 && i <= sl)
+  {
+    int sri= S_2_R[i];
+    if (sri >= 0 && sri <= tl)
+    {
+      TObject* t = R[sri];
+      if (t != NULL && t->p == S[i])
+        return t;
+    }
+    // last but not least, try kFindInT
+    sri = kFindInT(S[i], T, tl);
+    if (sri >= 0)
+      return &(T[sri]);
+  }
+  return NULL;
+}
+
+KINLINE poly skStrategy::kNoetherTail()
+{
+  if (tailRing == currRing)
+    return kNoether;
+  else
+  {
+    assume((kNoether == NULL && t_kNoether == NULL) ||
+           (kNoether != NULL && t_kNoether != NULL));
+    return t_kNoether;
+  }
+}
+
+/***************************************************************
+ *
+ * Operation on TObjects
+ *
+ ***************************************************************/
+
+KINLINE TSet initT ()
+{
+  TSet T = (TSet)omAlloc0(setmaxT*sizeof(TObject));
+  for (int i=setmaxT-1; i>=0; i--)
+  {
+    T[i].tailRing = currRing;
+    T[i].i_r = -1;
+  }
+  return T;
+}
+
+KINLINE TObject** initR()
+{
+  return (TObject**) omAlloc0(setmaxT*sizeof(TObject*));
+}
+
+KINLINE unsigned long* initsevT()
+{
+  return (unsigned long*) omAlloc0(setmaxT*sizeof(unsigned long));
+}
+
+// initialization
+KINLINE void sTObject::Set(ring r)
+{
+  tailRing = r;
+}
+KINLINE void sTObject::Init(ring r)
+{
+  memset(this, 0, sizeof(sTObject));
+  i_r = -1;
+  Set(r);
+}
+KINLINE sTObject::sTObject(ring r)
+{
+  Init(r);
+}
+KINLINE void sTObject::Set(poly p_in, ring r)
+{
+  if (r != currRing)
+  {
+    assume(r == tailRing);
+    p_Test(p_in, r);
+    t_p = p_in;
+  }
+  else
+  {
+    pp_Test(p_in, currRing, tailRing);
+    p = p_in;
+  }
+}
+
+KINLINE sTObject::sTObject(poly p_in, ring r)
+{
+  Init(r);
+  Set(p_in, r);
+}
+
+KINLINE void sTObject::Set(poly p_in, ring c_r, ring t_r)
+{
+  if (c_r != t_r)
+  {
+    assume(c_r == currRing && t_r == tailRing);
+    pp_Test(p_in, currRing, t_r);
+    p = p_in;
+  }
+  else
+  {
+    Set(p_in, c_r);
+  }
+}
+
+KINLINE sTObject::sTObject(poly p_in, ring c_r, ring t_r)
+{
+  Init(t_r);
+  Set(p_in, c_r, t_r);
+}
+
+KINLINE sTObject::sTObject(sTObject* T, int copy)
+{
+  *this = *T;
+  if (copy)
+  {
+    if (t_p != NULL)
+    {
+      t_p = p_Copy(t_p, tailRing);
+      p = k_LmInit_tailRing_2_currRing(t_p, tailRing);
+    }
+    else
+    {
+      p = p_Copy(p, currRing, tailRing);
+    }
+  }
+}
+
+KINLINE void sTObject::Delete()
+{
+  if (t_p != NULL)
+  {
+    p_Delete(&t_p, tailRing);
+    if (p != NULL)
+      p_LmFree(p, currRing);
+  }
+  else
+  {
+    p_Delete(&p, currRing, tailRing);
+  }
+}
+
+KINLINE void sTObject::Clear()
+{
+  p = NULL;
+  t_p = NULL;
+  ecart = 0;
+  length = 0;
+  pLength = 0;
+  FDeg = 0;
+  is_normalized = FALSE;
+}
+
+KINLINE void sTObject::Copy()
+{
+  if (t_p != NULL)
+  {
+    t_p = p_Copy(t_p, tailRing);
+    if (p != NULL)
+    {
+      p = p_Head(p, currRing);
+      if (pNext(t_p) != NULL) pNext(p) = pNext(t_p);
+    }
+  }
+  else
+  {
+    p = p_Copy(p, currRing, tailRing);
+  }
+}
+
+KINLINE poly sTObject::GetLmCurrRing()
+{
+  if (p == NULL && t_p != NULL)
+    p = k_LmInit_tailRing_2_currRing(t_p, tailRing);
+
+  return p;
+}
+KINLINE poly sTObject::GetLmTailRing()
+{
+  if (t_p == NULL)
+  {
+    if (p != NULL && tailRing != currRing)
+    {
+      t_p = k_LmInit_currRing_2_tailRing(p, tailRing);
+      return t_p;
+    }
+    return p;
+  }
+  return t_p;
+}
+KINLINE poly sTObject::GetLm(ring r)
+{
+  assume(r == tailRing || r == currRing);
+  if (r == currRing)
+    return GetLmCurrRing();
+
+  if (t_p == NULL && p != NULL)
+    t_p = k_LmInit_currRing_2_tailRing(p, tailRing);
+
+  return t_p;
+}
+
+KINLINE void sTObject::GetLm(poly &p_r, ring &r_r) const
+{
+  if (t_p != NULL)
+  {
+    p_r = t_p;
+    r_r = tailRing;
+  }
+  else
+  {
+    p_r = p;
+    r_r = currRing;
+  }
+}
+
+KINLINE BOOLEAN sTObject::IsNull() const
+{
+  return (p == NULL && t_p == NULL);
+}
+
+KINLINE int sTObject::GetpLength()
+{
+  if (pLength <= 0) pLength = ::pLength(p != NULL ? p : t_p);
+  return pLength;
+}
+
+KINLINE void sTObject::SetLmCurrRing()
+{
+  if (p == NULL && t_p != NULL)
+    p = k_LmInit_tailRing_2_currRing(t_p, tailRing);
+}
+
+KINLINE poly sTObject::Next()
+{
+  assume(p != NULL || t_p != NULL);
+  if (t_p != NULL) return pNext(t_p);
+  return pNext(p);
+}
+
+// Iterations
+KINLINE void sTObject::LmDeleteAndIter()
+{
+  assume(p != NULL || t_p != NULL);
+  if (t_p != NULL)
+  {
+    t_p = p_LmDeleteAndNext(t_p, tailRing);
+    if (p != NULL)
+    {
+      p_LmFree(p, currRing);
+      p = NULL;
+    }
+  }
+  else
+  {
+    p = p_LmDeleteAndNext(p, currRing);
+  }
+  is_normalized = FALSE;
+}
+
+
+// arithmetic
+KINLINE void sTObject::Mult_nn(number n)
+{
+  if (t_p != NULL)
+  {    t_p = tailRing->p_Procs->p_Mult_nn(t_p, n, tailRing);
+    if (p != NULL) pSetCoeff0(p, pGetCoeff(t_p));
+  }
+  else
+  {
+    p = p_Mult_nn(p, n, currRing, tailRing);
+  }
+}
+
+KINLINE void
+sTObject::ShallowCopyDelete(ring new_tailRing, omBin new_tailBin,
+                            pShallowCopyDeleteProc p_shallow_copy_delete,
+                            BOOLEAN set_max)
+{
+  if (new_tailBin == NULL) new_tailBin = new_tailRing->PolyBin;
+  if (t_p != NULL)
+  {
+    t_p = p_shallow_copy_delete(t_p, tailRing, new_tailRing, new_tailBin);
+    if (p != NULL)
+      pNext(p) = pNext(t_p);
+    if (new_tailRing == currRing)
+    {
+      if (p == NULL) p = t_p;
+      else p_LmFree(t_p, tailRing);
+      t_p = NULL;
+    }
+  }
+  else if (p != NULL)
+  {
+    if (pNext(p) != NULL)
+    {
+      pNext(p) = p_shallow_copy_delete(pNext(p),
+                                       tailRing, new_tailRing, new_tailBin);
+    }
+    if (new_tailRing != currRing)
+    {
+      t_p = k_LmInit_currRing_2_tailRing(p, new_tailRing);
+      pNext(t_p) = pNext(p);
+    }
+  }
+  if (max != NULL)
+  {
+    if (new_tailRing == currRing)
+    {
+      p_LmFree(max, tailRing);
+      max = NULL;
+    }
+    else
+      max = p_shallow_copy_delete(max,tailRing,new_tailRing,new_tailBin);
+  }
+  else if (set_max && new_tailRing != currRing && pNext(t_p) != NULL)
+  {
+    max = p_GetMaxExpP(pNext(t_p), new_tailRing);
+  }
+  tailRing = new_tailRing;
+}
+
+KINLINE long sTObject::pFDeg() const
+{
+  if (p != NULL) return ::pFDeg(p, currRing);
+  return tailRing->pFDeg(t_p, tailRing);
+}
+KINLINE long sTObject::SetpFDeg()
+{
+  FDeg = this->pFDeg();
+  return FDeg;
+}
+KINLINE long sTObject::GetpFDeg() const
+{
+  assume(FDeg == this->pFDeg());
+  return FDeg;
+}
+KINLINE long sTObject::pLDeg()
+{
+  return tailRing->pLDeg(GetLmTailRing(), &length, tailRing);
+}
+KINLINE long sTObject::SetDegStuffReturnLDeg()
+{
+  FDeg = this->pFDeg();
+  long d = this->pLDeg();
+  ecart = d - FDeg;
+  return d;
+}
+
+extern void pCleardenom(poly p);
+extern void pNorm(poly p);
+// manipulations
+KINLINE void  sTObject::pCleardenom()
+{
+  assume(p != NULL);
+  ::pCleardenom(p);
+  if (t_p != NULL)
+    pSetCoeff0(t_p, pGetCoeff(p));
+}
+
+KINLINE void  sTObject::pNorm()
+{
+  assume(p != NULL);
+  if (! is_normalized)
+  {
+    ::pNorm(p);
+    if (t_p != NULL)
+      pSetCoeff0(t_p, pGetCoeff(p));
+    is_normalized = TRUE;
+  }
+}
+
+
+
+/***************************************************************
+ *
+ * Operation on LObjects
+ *
+ ***************************************************************/
+// Initialization
+KINLINE void sLObject::Clear()
+{
+  sTObject::Clear();
+  sev = 0;
+}
+// Initialization
+KINLINE void sLObject::Delete()
+{
+  sTObject::Delete();
+  if (bucket != NULL)
+    kBucketDeleteAndDestroy(&bucket);
+}
+
+KINLINE void sLObject::Init(ring r)
+{
+  memset(this, 0, sizeof(sLObject));
+  i_r1 = -1;
+  i_r2 = -1;
+  i_r = -1;
+  Set(r);
+}
+KINLINE sLObject::sLObject(ring r)
+{
+  Init(r);
+}
+KINLINE sLObject::sLObject(poly p_in, ring r)
+{
+  Init(r);
+  Set(p_in, r);
+}
+
+KINLINE sLObject::sLObject(poly p_in, ring c_r, ring t_r)
+{
+  Init(t_r);
+  Set(p_in, c_r, t_r);
+}
+
+KINLINE void sLObject::PrepareRed(BOOLEAN use_bucket)
+{
+  if (bucket == NULL)
+  {
+    int l = GetpLength();
+    if (use_bucket && l > 1)
+    {
+      poly tp = GetLmTailRing();
+      assume(l == ::pLength(tp));
+      bucket = kBucketCreate(tailRing);
+      kBucketInit(bucket, pNext(tp), l-1);
+      pNext(tp) = NULL;
+      if (p != NULL) pNext(p) = NULL;
+      pLength = 0;
+      last = NULL;
+    }
+  }
+}
+
+KINLINE void sLObject::SetLmTail(poly lm, poly p_tail, int p_Length, int use_bucket, ring tailRing, poly _last)
+{
+
+  Set(lm, tailRing);
+  if (use_bucket)
+  {
+    bucket = kBucketCreate(tailRing);
+    kBucketInit(bucket, p_tail, p_Length);
+    pNext(lm) = NULL;
+    pLength = 0;
+    last = NULL;
+  }
+  else
+  {
+    pNext(lm) = p_tail;
+    pLength = p_Length + 1;
+    last = _last;
+  }
+
+}
+
+KINLINE void sLObject::Tail_Mult_nn(number n)
+{
+  if (bucket != NULL)
+  {
+    kBucket_Mult_n(bucket, n);
+  }
+  else
+  {
+    poly _p = (t_p != NULL ? t_p : p);
+    assume(_p != NULL);
+    pNext(_p) = tailRing->p_Procs->p_Mult_nn(pNext(_p), n, tailRing);
+  }
+}
+
+KINLINE void sLObject::Tail_Minus_mm_Mult_qq(poly m, poly q, int lq,
+                                             poly spNoether)
+{
+  if (bucket != NULL)
+  {
+    kBucket_Minus_m_Mult_p(bucket, m, q, &lq, spNoether);
+  }
+  else
+  {
+    poly _p = (t_p != NULL ? t_p : p);
+    assume(_p != NULL);
+    int shorter;
+    pNext(_p) = tailRing->p_Procs->p_Minus_mm_Mult_qq(pNext(_p), m, q,
+                                                      shorter,spNoether,
+                                                      tailRing, last);
+    pLength += lq - shorter;
+  }
+}
+
+KINLINE void sLObject::LmDeleteAndIter()
+{
+  sTObject::LmDeleteAndIter();
+  if (bucket != NULL)
+  {
+    poly _p = kBucketExtractLm(bucket);
+    if (_p == NULL)
+    {
+      kBucketDestroy(&bucket);
+      p = t_p = NULL;
+      return;
+    }
+    Set(_p, tailRing);
+  }
+  else
+  {
+    pLength--;
+  }
+}
+
+KINLINE poly sLObject::LmExtractAndIter()
+{
+  poly ret = GetLmTailRing();
+  poly pn;
+
+  assume(p != NULL || t_p != NULL);
+
+  if (bucket != NULL)
+  {
+    pn = kBucketExtractLm(bucket);
+    if (pn == NULL)
+      kBucketDestroy(&bucket);
+  }
+  else
+  {
+    pn = pNext(ret);
+  }
+  pLength--;
+  pNext(ret) = NULL;
+  if (p != NULL && t_p != NULL)
+    p_LmFree(p, currRing);
+
+  Set(pn, tailRing);
+  return ret;
+}
+
+KINLINE poly sLObject::CanonicalizeP()
+{
+  kTest_L(this);
+  int i = -1;
+
+  if (bucket != NULL)
+    i = kBucketCanonicalize(bucket);
+
+  if (p == NULL)
+    p = k_LmInit_tailRing_2_currRing(t_p, tailRing);
+
+  if (i >= 0) pNext(p) = bucket->buckets[i];
+  return p;
+}
+
+KINLINE poly sLObject::GetTP()
+{
+  kTest_L(this);
+  poly tp = GetLmTailRing();
+  assume(tp != NULL);
+
+  if (bucket != NULL)
+  {
+    kBucketClear(bucket, &pNext(tp), &pLength);
+    kBucketDestroy(&bucket);
+    pLength++;
+  }
+  return tp;
+}
+
+
+KINLINE poly sLObject::GetP(omBin lmBin)
+{
+  kTest_L(this);
+  if (p == NULL)
+  {
+    p = k_LmInit_tailRing_2_currRing(t_p, tailRing,
+                                     (lmBin!=NULL?lmBin:currRing->PolyBin));
+    FDeg = pFDeg();
+  }
+  else if (lmBin != NULL && lmBin != currRing->PolyBin)
+  {
+    p = p_LmShallowCopyDelete(p, currRing, lmBin);
+    FDeg = pFDeg();
+  }
+
+  if (bucket != NULL)
+  {
+    kBucketClear(bucket, &pNext(p), &pLength);
+    kBucketDestroy(&bucket);
+    pLength++;
+    if (t_p != NULL) pNext(t_p) = pNext(p);
+  }
+  kTest_L(this);
+  return p;
+}
+
+KINLINE void
+sLObject::ShallowCopyDelete(ring new_tailRing,
+                            pShallowCopyDeleteProc p_shallow_copy_delete)
+{
+  if (bucket != NULL)
+    kBucketShallowCopyDelete(bucket, new_tailRing, new_tailRing->PolyBin,
+                             p_shallow_copy_delete);
+  sTObject::ShallowCopyDelete(new_tailRing,
+                              new_tailRing->PolyBin,p_shallow_copy_delete,
+                              FALSE);
+  last = NULL;
+}
+
+KINLINE void sLObject::SetShortExpVector()
+{
+  if (t_p != NULL)
+  {
+    sev = p_GetShortExpVector(t_p, tailRing);
+  }
+  else
+  {
+    sev = p_GetShortExpVector(p, currRing);
+  }
+}
+
+KINLINE void sLObject::Copy()
+{
+  if (bucket != NULL)
+  {
+    int i = kBucketCanonicalize(bucket);
+    kBucket_pt new_bucket = kBucketCreate(tailRing);
+    kBucketInit(new_bucket,
+                p_Copy(bucket->buckets[i], tailRing),
+                bucket->buckets_length[i]);
+    bucket = new_bucket;
+    if (t_p != NULL) pNext(t_p) = NULL;
+    if (p != NULL) pNext(p) = NULL;
+  }
+  TObject::Copy();
+  last = NULL;
+}
+
+KINLINE poly sLObject::CopyGetP()
+{
+  last = NULL;
+  if (bucket != NULL)
+  {
+    int i = kBucketCanonicalize(bucket);
+    poly bp = p_Copy(bucket->buckets[i], tailRing);
+    pLength = bucket->buckets_length[i] + 1;
+    if (bp != NULL)
+    {
+      assume(t_p != NULL || p != NULL);
+      if (t_p != NULL) pNext(t_p) = bp;
+      else pNext(p) = bp;
+    }
+    bucket = NULL;
+  }
+  return sLObject::GetP();
+}
+
+
+KINLINE long sLObject::pLDeg()
+{
+  poly tp = GetLmTailRing();
+  assume(tp != NULL);
+  if (bucket != NULL)
+  {
+    int i = kBucketCanonicalize(bucket);
+    pNext(tp) = bucket->buckets[i];
+    long ldeg = tailRing->pLDeg(tp, &length, tailRing);
+    pNext(tp) = NULL;
+    return ldeg;
+  }
+  else
+    return tailRing->pLDeg(tp, &length, tailRing);
+}
+KINLINE long sLObject::pLDeg(BOOLEAN deg_last)
+{
+  if (! deg_last || bucket != NULL) return sLObject::pLDeg();
+
+  if (last == NULL || pLength == 0)
+    last = pLast(GetLmTailRing(), pLength);
+#ifdef HAVE_ASSUME
+  long fdeg;
+  fdeg = tailRing->pLDeg(GetLmTailRing(), &length, tailRing);
+  assume (pLength == length && fdeg == tailRing->pFDeg(last, tailRing));
+  return fdeg;
+#else
+  length = pLength;
+  return tailRing->pFDeg(last, tailRing);
+#endif
+}
+
+KINLINE long sLObject::SetDegStuffReturnLDeg()
+{
+  FDeg = this->pFDeg();
+  long d = this->pLDeg();
+  ecart = d - FDeg;
+  return d;
+}
+KINLINE long sLObject::SetDegStuffReturnLDeg(BOOLEAN use_last)
+{
+  FDeg = this->pFDeg();
+  long d = this->pLDeg(use_last);
+  ecart = d - FDeg;
+  return d;
+}
+KINLINE int sLObject::GetpLength()
+{
+  if (bucket == NULL)
+    return sTObject::GetpLength();
+  int i = kBucketCanonicalize(bucket);
+  return bucket->buckets_length[i] + 1;
+}
+KINLINE int sLObject::SetLength(BOOLEAN length_pLength)
+{
+  if (length_pLength)
+  {
+    length = this->GetpLength();
+  }
+  else
+    this->pLDeg();
+  return length;
+}
+KINLINE long sLObject::MinComp()
+{
+  poly tp = GetLmTailRing();
+  assume(tp != NULL);
+  if (bucket != NULL)
+  {
+    int i = kBucketCanonicalize(bucket);
+    pNext(tp) = bucket->buckets[i];
+    long m = p_MinComp(tp, tailRing);
+    pNext(tp) = NULL;
+    return m;
+  }
+  else
+    return p_MinComp(tp, tailRing);
+}
+KINLINE long sLObject::Comp()
+{
+  poly p;
+  ring r;
+  GetLm(p, r);
+  assume(p != NULL);
+  return p_GetComp(p, r);
+}
+
+KINLINE sLObject& sLObject::operator=(const sTObject& t)
+{
+  memset(this, 0, sizeof(*this));
+  memcpy(this, &t, sizeof(sTObject));
+  return *this;
+}
+
+KINLINE TObject* sLObject::T_1(const skStrategy* s)
+{
+  if (p1 == NULL) return NULL;
+  if (i_r1 == -1) i_r1 = kFindInT(p1, s->T, s->tl);
+  assume(i_r1 >= 0 && i_r1 <= s->tl);
+  TObject* T = s->R[i_r1];
+  assume(T->p == p1);
+  return T;
+}
+
+KINLINE TObject* sLObject::T_2(const skStrategy* strat)
+{
+  if (p1 == NULL) return NULL;
+  assume(p2 != NULL);
+  if (i_r2 == -1) i_r2 = kFindInT(p2, strat->T, strat->tl);
+  assume(i_r2 >= 0 && i_r2 <= strat->tl);
+  TObject* T = strat->R[i_r2];
+  assume(T->p == p2);
+  return T;
+}
+
+KINLINE void    sLObject::T_1_2(const skStrategy* strat,
+                                TObject* &T_1, TObject* &T_2)
+{
+  if (p1 == NULL)
+  {
+    T_1 = NULL;
+    T_2 = NULL;
+    return;
+  }
+  assume(p1 != NULL && p2 != NULL);
+  if (i_r1 == -1) i_r1 = kFindInT(p1, strat->T, strat->tl);
+  if (i_r2 == -1) i_r2 = kFindInT(p2, strat->T, strat->tl);
+  assume(i_r1 >= 0 && i_r1 <= strat->tl);
+  assume(i_r2 >= 0 && i_r2 <= strat->tl);
+  T_1 = strat->R[i_r1];
+  T_2 = strat->R[i_r2];
+  assume(T_1->p == p1);
+  assume(T_2->p == p2);
+  return;
+}
+
+/***************************************************************
+ *
+ * Conversion of polys
+ *
+ ***************************************************************/
+
+KINLINE poly k_LmInit_currRing_2_tailRing(poly p, ring tailRing, omBin tailBin)
+{
+
+  poly np = p_LmInit(p, currRing, tailRing, tailBin);
+  pNext(np) = pNext(p);
+  pSetCoeff0(np, pGetCoeff(p));
+  return np;
+}
+
+KINLINE poly k_LmInit_tailRing_2_currRing(poly p, ring tailRing, omBin lmBin)
+{
+  poly np = p_LmInit(p, tailRing, currRing, lmBin);
+  pNext(np) = pNext(p);
+  pSetCoeff0(np, pGetCoeff(p));
+  return np;
+}
+
+// this should be made more efficient
+KINLINE poly k_LmShallowCopyDelete_currRing_2_tailRing(poly p, ring tailRing, omBin tailBin)
+{
+  poly np = k_LmInit_currRing_2_tailRing(p, tailRing, tailBin);
+  p_LmFree(p, currRing);
+  return np;
+}
+
+KINLINE poly k_LmShallowCopyDelete_tailRing_2_currRing(poly p, ring tailRing, omBin lmBin)
+{
+  poly np = k_LmInit_tailRing_2_currRing(p, tailRing, lmBin);
+  p_LmFree(p, tailRing);
+  return np;
+}
+
+KINLINE poly k_LmInit_currRing_2_tailRing(poly p, ring tailRing)
+{
+  return k_LmInit_currRing_2_tailRing(p, tailRing, tailRing->PolyBin);
+}
+
+KINLINE poly k_LmInit_tailRing_2_currRing(poly p, ring tailRing)
+{
+  return  k_LmInit_tailRing_2_currRing(p, tailRing, currRing->PolyBin);
+}
+
+KINLINE poly k_LmShallowCopyDelete_currRing_2_tailRing(poly p, ring tailRing)
+{
+  return k_LmShallowCopyDelete_currRing_2_tailRing(p, tailRing, tailRing->PolyBin);
+}
+
+KINLINE poly k_LmShallowCopyDelete_tailRing_2_currRing(poly p, ring tailRing)
+{
+  return  k_LmShallowCopyDelete_tailRing_2_currRing(p, tailRing, currRing->PolyBin);
+}
+
+/***************************************************************
+ *
+ * Lcm business
+ *
+ ***************************************************************/
+// get m1 = LCM(LM(p1), LM(p2))/LM(p1)
+//     m2 = LCM(LM(p1), LM(p2))/LM(p2)
+KINLINE BOOLEAN k_GetLeadTerms(const poly p1, const poly p2, const ring p_r,
+                               poly &m1, poly &m2, const ring m_r)
+{
+  p_LmCheckPolyRing(p1, p_r);
+  p_LmCheckPolyRing(p2, p_r);
+
+  int i;
+  Exponent_t x;
+  m1 = p_Init(m_r);
+  m2 = p_Init(m_r);
+
+  for (i = p_r->N; i; i--)
+  {
+    x = p_GetExpDiff(p1, p2, i, p_r);
+    if (x > 0)
+    {
+      if (x > (long) m_r->bitmask) goto false_return;
+      p_SetExp(m2,i,x, m_r);
+      p_SetExp(m1,i,0, m_r);
+    }
+    else
+    {
+      if (-x > (long) m_r->bitmask) goto false_return;
+      p_SetExp(m1,i,-x, m_r);
+      p_SetExp(m2,i,0, m_r);
+    }
+  }
+
+  p_Setm(m1, m_r);
+  p_Setm(m2, m_r);
+  return TRUE;
+
+  false_return:
+  p_LmFree(m1, m_r);
+  p_LmFree(m2, m_r);
+  m1 = m2 = NULL;
+  return FALSE;
+}
+
+/***************************************************************
+ *
+ * Misc things
+ *
+ ***************************************************************/
+KINLINE int ksReducePolyTail(LObject* PR, TObject* PW, LObject* Red)
+{
+  BOOLEAN ret;
+  number coef;
+
+  assume(PR->GetLmCurrRing() != PW->GetLmCurrRing());
+  ret = ksReducePoly(Red, PW, NULL, &coef);
+
+  if (!ret)
+  {
+    if (! n_IsOne(coef, currRing))
+      PR->Mult_nn(coef);
+    n_Delete(&coef, currRing);
+  }
+  return ret;
+}
+
+/***************************************************************
+ *
+ * Routines for backwards-Compatibility
+ *
+ *
+ ***************************************************************/
+KINLINE poly ksOldSpolyRed(poly p1, poly p2, poly spNoether)
+{
+  LObject L(p2);
+  TObject T(p1);
+
+  ksReducePoly(&L, &T, spNoether);
+
+  return L.GetLmCurrRing();
+}
+
+KINLINE poly ksOldSpolyRedNew(poly p1, poly p2, poly spNoether)
+{
+  LObject L(p_Copy(p2, currRing));
+  TObject T(p1);
+
+  ksReducePoly(&L, &T, spNoether);
+
+  return L.GetLmCurrRing();
+}
+
+KINLINE poly ksOldCreateSpoly(poly p1, poly p2, poly spNoether, ring r)
+{
+  LObject L(r);
+  L.p1 = p1;
+  L.p2 = p2;
+
+  ksCreateSpoly(&L, spNoether);
+  return L.GetLmCurrRing();
+}
+
+void ksOldSpolyTail(poly p1, poly q, poly q2, poly spNoether, ring r)
+{
+  LObject L(q,  currRing, r);
+  TObject T(p1, currRing, r);
+
+  ksReducePolyTail(&L, &T, q2, spNoether);
+}
+
+KINLINE poly redtailBba (poly p,int pos,kStrategy strat)
+{
+  LObject L(p, currRing, strat->tailRing);
+  return redtailBba(&L, pos, strat);
+}
+
+KINLINE poly redtailBba(TObject *T, int pos,kStrategy strat, BOOLEAN withT)
+{
+  LObject L;
+  L = *T;
+  poly p = redtailBba(&L, pos, strat, FALSE);
+  *T = L;
+  kTest_T(T);
+  assume( p == T->p);
+  return p;
+}
+
+#endif // defined(KINLINE) || defined(KUTIL_CC)
+#endif // KINLINE_CC
Index: kernel/kbuckets.cc
===================================================================
--- kernel/kbuckets.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/kbuckets.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,815 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: kbuckets.cc,v 1.1.1.1 2003-10-06 12:15:56 Singular Exp $ */
+
+#include "mod2.h"
+#include "structs.h"
+#include "omalloc.h"
+#include "p_polys.h"
+#include "febase.h"
+#include "pShallowCopyDelete.h"
+#include "kbuckets.h"
+#include "numbers.h"
+#include "p_Procs.h"
+
+#ifdef HAVE_COEF_BUCKETS
+#define USE_COEF_BUCKETS
+#endif
+
+#ifdef USE_COEF_BUCKETS
+#define MULTIPLY_BUCKET(B,I) do                                        \
+  { if (B->coef[I]!=NULL)                                              \
+    {                                                                  \
+      B->buckets[I]=p_Mult_q(B->buckets[I],B->coef[I],B->bucket_ring); \
+      B->coef[I]=NULL;                                                 \
+    }                                                                  \
+  } while(0)
+#else
+#define MULTIPLY_BUCKET(B,I)
+#endif
+static omBin kBucket_bin = omGetSpecBin(sizeof(kBucket));
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Some internal stuff
+///
+
+// returns ceil(log_4(l))
+inline unsigned int pLogLength(unsigned int l)
+{
+  unsigned int i = 0;
+
+  if (l == 0) return 0;
+  l--;
+#ifdef BUCKET_TWO_BASE
+  while ((l = (l >> 1))) i++;
+#else
+  while ((l = (l >> 2))) i++;
+#endif
+  return i+1;
+}
+
+// returns ceil(log_4(pLength(p)))
+inline unsigned int pLogLength(poly p)
+{
+  return pLogLength((unsigned int) pLength(p));
+}
+
+#ifdef KDEBUG
+
+#ifndef HAVE_PSEUDO_BUCKETS
+BOOLEAN kbTest_i(kBucket_pt bucket, int i)
+{
+  #ifdef USE_COEF_BUCKETS
+  assume(bucket->coef[0]==NULL);
+  if ((bucket->coef[i]!=NULL) && (bucket->buckets[i]==NULL))
+  {
+    dReportError("Bucket %d coef not NULL", i);
+  }
+  if (bucket->coef[i]!=NULL)
+    _p_Test(bucket->coef[i],bucket->bucket_ring,PDEBUG);
+  #endif
+  pFalseReturn(p_Test(bucket->buckets[i], bucket->bucket_ring));
+  if (bucket->buckets_length[i] != pLength(bucket->buckets[i]))
+  {
+    dReportError("Bucket %d lengths difference should:%d has:%d",
+                 i, bucket->buckets_length[i], pLength(bucket->buckets[i]));
+  }
+  else if (i > 0 && (int) pLogLength(bucket->buckets_length[i]) > i)
+  {
+    dReportError("Bucket %d too long %d",
+                 i, bucket->buckets_length[i]);
+  }
+  if (i==0 && bucket->buckets_length[0] > 1)
+  {
+    dReportError("Bucket 0 too long");
+  }
+  return TRUE;
+}
+
+
+BOOLEAN kbTest(kBucket_pt bucket)
+{
+  int i;
+  poly lm = bucket->buckets[0];
+
+  omCheckAddrBin(bucket, kBucket_bin);
+  if (! kbTest_i(bucket, 0)) return FALSE;
+  for (i=1; i<= (int) bucket->buckets_used; i++)
+  {
+    if (!kbTest_i(bucket, i)) return FALSE;
+    if (lm != NULL &&  bucket->buckets[i] != NULL
+        && p_LmCmp(lm, bucket->buckets[i], bucket->bucket_ring) != 1)
+    {
+      dReportError("Bucket %d larger than lm", i);
+      return FALSE;
+    }
+    if (!p_Test(bucket->buckets[i],bucket->bucket_ring))
+    {
+      dReportError("Bucket %d is not =0(4)", i);
+      return FALSE;
+    }
+  }
+
+  for (; i<=MAX_BUCKET; i++)
+  {
+    if (bucket->buckets[i] != NULL || bucket->buckets_length[i] != 0)
+    {
+      dReportError("Bucket %d not zero", i);
+      return FALSE;
+    }
+  }
+  return TRUE;
+}
+
+#else // HAVE_PSEUDO_BUCKETS
+BOOLEAN kbTest(kBucket_pt bucket)
+{
+  return TRUE;
+}
+#endif // ! HAVE_PSEUDO_BUCKETS
+#endif // KDEBUG
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Creation/Destruction of buckets
+///
+
+kBucket_pt kBucketCreate(ring bucket_ring)
+{
+  assume(bucket_ring != NULL);
+  kBucket_pt bucket = (kBucket_pt) omAlloc0Bin(kBucket_bin);
+  bucket->bucket_ring = bucket_ring;
+  return bucket;
+}
+void kBucketDestroy(kBucket_pt *bucket_pt)
+{
+  omFreeBin(*bucket_pt, kBucket_bin);
+  *bucket_pt = NULL;
+}
+
+
+void kBucketDeleteAndDestroy(kBucket_pt *bucket_pt)
+{
+  kBucket_pt bucket = *bucket_pt;
+  kbTest(bucket);
+  int i;
+  for (i=0; i<= bucket->buckets_used; i++)
+  {
+    if (bucket->buckets[i] != NULL)
+    {
+      p_Delete(&(bucket->buckets[i]), bucket->bucket_ring);
+#ifdef USE_COEF_BUCKETS
+      if (bucket->coef[i]!=NULL)
+        p_Delete(&(bucket->coef[i]), bucket->bucket_ring);
+#endif
+    }
+  }
+  omFreeBin(bucket, kBucket_bin);
+  *bucket_pt = NULL;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Convertion from/to Bpolys
+//
+#ifndef HAVE_PSEUDO_BUCKETS
+
+inline void kBucketMergeLm(kBucket_pt bucket)
+{
+  if (bucket->buckets[0] != NULL)
+  {
+    poly lm = bucket->buckets[0];
+    int i = 1;
+#ifdef BUCKET_TWO_BASE
+    int l = 2;
+    while ( bucket->buckets_length[i] >= l)
+    {
+      i++;
+      l = l << 1;
+    }
+#else
+    int l = 4;
+    while ( bucket->buckets_length[i] >= l)
+    {
+      i++;
+      l = l << 2;
+    }
+#endif
+    MULTIPLY_BUCKET(bucket,i);
+    pNext(lm) = bucket->buckets[i];
+    bucket->buckets[i] = lm;
+    bucket->buckets_length[i]++;
+    assume(i <= bucket->buckets_used+1);
+    if (i > bucket->buckets_used)  bucket->buckets_used = i;
+    bucket->buckets[0] = NULL;
+    bucket->buckets_length[0] = 0;
+  }
+}
+
+static BOOLEAN kBucketIsCleared(kBucket_pt bucket)
+{
+  int i;
+
+  for (i = 0;i<=MAX_BUCKET;i++)
+  {
+    if (bucket->buckets[i] != NULL) return FALSE;
+    if (bucket->buckets_length[i] != 0) return FALSE;
+  }
+  return TRUE;
+}
+
+void kBucketInit(kBucket_pt bucket, poly lm, int length)
+{
+  assume(bucket != NULL);
+  assume(length <= 0 || length == pLength(lm));
+  assume(kBucketIsCleared(bucket));
+
+  if (lm == NULL) return;
+
+  if (length <= 0)
+    length = pLength(lm);
+
+  bucket->buckets[0] = lm;
+  bucket->buckets_length[0] = 1;
+  if (length > 1)
+  {
+    unsigned int i = pLogLength(length-1);
+    bucket->buckets[i] = pNext(lm);
+    pNext(lm) = NULL;
+    bucket->buckets_length[i] = length-1;
+    bucket->buckets_used = i;
+  }
+  else
+  {
+    bucket->buckets_used = 0;
+  }
+}
+
+int kBucketCanonicalize(kBucket_pt bucket)
+{
+  kbTest(bucket);
+  poly p = bucket->buckets[1];
+  poly lm;
+  int pl = bucket->buckets_length[1], i;
+  bucket->buckets[1] = NULL;
+  bucket->buckets_length[1] = 0;
+  ring r=bucket->bucket_ring;
+
+
+  for (i=2; i<=bucket->buckets_used; i++)
+  {
+  #ifdef USE_COEF_BUCKETS
+    if (bucket->coef[i]!=NULL)
+    {
+      p = p_Plus_mm_Mult_qq(p, bucket->coef[i], bucket->buckets[i],
+                 pl, bucket->buckets_length[i], r);
+      p_Delete(&bucket->coef[i],r);
+      p_Delete(&bucket->buckets[i],r);
+    }
+    else
+    p = p_Add_q(p, bucket->buckets[i],
+                 pl, bucket->buckets_length[i], r);
+  #else
+    q = p_Add_q(q, bucket->buckets[i],
+                 pl, bucket->buckets_length[i], r);
+  #endif
+    bucket->buckets[i] = NULL;
+    bucket->buckets_length[i] = 0;
+  }
+
+  lm = bucket->buckets[0];
+  if (lm != NULL)
+  {
+    pNext(lm) = p;
+    p = lm;
+    pl++;
+    bucket->buckets[0] = NULL;
+    bucket->buckets_length[0] = 0;
+  }
+  if (pl > 0)
+  {
+    i = pLogLength(pl);
+    bucket->buckets[i] = p;
+    bucket->buckets_length[i] = pl;
+  }
+  else
+  {
+    i = 0;
+  }
+  bucket->buckets_used = i;
+  assume(pLength(p) == (int) pl);
+  kbTest(bucket);
+  return i;
+}
+
+void kBucketClear(kBucket_pt bucket, poly *p, int *length)
+{
+  int i = kBucketCanonicalize(bucket);
+  if (i > 0)
+  {
+    *p = bucket->buckets[i];
+    *length = bucket->buckets_length[i];
+    bucket->buckets[i] = NULL;
+    bucket->buckets_length[i] = 0;
+    bucket->buckets_used = 0;
+#ifdef USE_COEF_BUCKETS
+    bucket->coef[i]=NULL;
+#endif
+  }
+  else
+  {
+    *p = NULL;
+    *length = 0;
+  }
+}
+
+void kBucketSetLm(kBucket_pt bucket, poly lm)
+{
+  kBucketMergeLm(bucket);
+  pNext(lm) = NULL;
+  bucket->buckets[0] = lm;
+  bucket->buckets_length[0] = 1;
+}
+
+#else // HAVE_PSEUDO_BUCKETS
+
+void kBucketInit(kBucket_pt bucket, poly lm, int length)
+{
+  int i;
+
+  assume(bucket != NULL);
+  assume(length <= 0 || length == pLength(lm));
+
+  bucket->p = lm;
+  if (length <= 0) bucket->l = pLength(lm);
+  else bucket->l = length;
+
+}
+
+const poly kBucketGetLm(kBucket_pt bucket)
+{
+  return bucket->p;
+}
+
+poly kBucketExtractLm(kBucket_pt bucket)
+{
+  poly lm = bucket->p;
+  assume(pLength(bucket->p) == bucket->l);
+  pIter(bucket->p);
+  (bucket->l)--;
+  pNext(lm) = NULL;
+  return lm;
+}
+
+void kBucketClear(kBucket_pt bucket, poly *p, int *length)
+{
+  assume(pLength(bucket->p) == bucket->l);
+  *p = bucket->p;
+  *length = bucket->l;
+  bucket->p = NULL;
+  bucket->l = 0;
+}
+
+#endif // ! HAVE_PSEUDO_BUCKETS
+//////////////////////////////////////////////////////////////////////////
+///
+/// For changing the ring of the Bpoly to new_tailBin
+///
+void kBucketShallowCopyDelete(kBucket_pt bucket,
+                              ring new_tailRing, omBin new_tailBin,
+                              pShallowCopyDeleteProc p_shallow_copy_delete)
+{
+#ifndef HAVE_PSEUDO_BUCKETS
+  int i;
+
+  kBucketCanonicalize(bucket);
+  for (i=0; i<= bucket->buckets_used; i++)
+    if (bucket->buckets[i] != NULL)
+    {
+      MULTIPLY_BUCKET(bucket,i);
+      bucket->buckets[i] = p_shallow_copy_delete(bucket->buckets[i],
+                                                 bucket->bucket_ring,
+                                                 new_tailRing,
+                                                 new_tailBin);
+    }
+#else
+  bucket->p = p_shallow_copy_delete(p,
+                                    bucket_ring,
+                                    new_tailRing,
+                                    new_tailBin);
+#endif
+  bucket->bucket_ring = new_tailRing;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Multiply Bucket by number ,i.e. Bpoly == n*Bpoly
+///
+void kBucket_Mult_n(kBucket_pt bucket, number n)
+{
+#ifndef HAVE_PSEUDO_BUCKETS
+  kbTest(bucket);
+  ring r=bucket->bucket_ring;
+  int i;
+
+  for (i=0; i<= bucket->buckets_used; i++)
+  {
+    if (bucket->buckets[i] != NULL)
+    {
+#ifdef USE_COEF_BUCKETS
+      if (i<2)
+        bucket->buckets[i] = p_Mult_nn(bucket->buckets[i], n, r);
+      else
+      if (bucket->coef[i]!=NULL)
+      {
+        bucket->coef[i] = p_Mult_nn(bucket->coef[i],n,r);
+      }
+      else
+      {
+        bucket->coef[i] = p_NSet(n_Copy(n,bucket->bucket_ring),r);
+      }
+#else
+      bucket->buckets[i] = p_Mult_nn(bucket->buckets[i], n, r);
+#endif
+    }
+  }
+  kbTest(bucket);
+#else
+  bucket->p = p_Mult_nn(bucket->p, n, bucket->bucket_ring);
+#endif
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Add to Bucket a poly ,i.e. Bpoly == n*Bpoly
+///
+void kBucket_Add_q(kBucket_pt bucket, poly q, int *l)
+{
+  if (q == NULL) return;
+  assume(*l <= 0 || pLength(q) == *l);
+
+  int i, l1;
+  ring r = bucket->bucket_ring;
+
+  if (*l <= 0)
+  {
+    l1 = pLength(q);
+    *l = l1;
+  }
+  else
+    l1 = *l;
+
+  kBucketMergeLm(bucket);
+  kbTest(bucket);
+  i = pLogLength(l1);
+
+  while (bucket->buckets[i] != NULL)
+  {
+    //MULTIPLY_BUCKET(bucket,i);
+  #ifdef USE_COEF_BUCKETS
+    if (bucket->coef[i]!=NULL)
+    {
+      q = p_Plus_mm_Mult_qq(q, bucket->coef[i], bucket->buckets[i],
+                 l1, bucket->buckets_length[i], r);
+      p_Delete(&bucket->coef[i],r);
+      p_Delete(&bucket->buckets[i],r);
+    }
+    else
+    q = p_Add_q(q, bucket->buckets[i],
+                 l1, bucket->buckets_length[i], r);
+  #else
+    q = p_Add_q(q, bucket->buckets[i],
+                 l1, bucket->buckets_length[i], r);
+  #endif
+    bucket->buckets[i] = NULL;
+    bucket->buckets_length[i] = 0;
+    i = pLogLength(l1);
+  }
+
+  bucket->buckets[i] = q;
+  bucket->buckets_length[i]=l1;
+  if (i >= bucket->buckets_used)
+    bucket->buckets_used = i;
+  else
+    kBucketAdjustBucketsUsed(bucket);
+  kbTest(bucket);
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Bpoly == Bpoly - m*p; where m is a monom
+/// Does not destroy p and m
+/// assume (*l <= 0 || pLength(p) == *l)
+void kBucket_Minus_m_Mult_p(kBucket_pt bucket, poly m, poly p, int *l,
+                            poly spNoether)
+{
+  assume(*l <= 0 || pLength(p) == *l);
+  int i, l1;
+  poly p1 = p;
+  poly last;
+  ring r = bucket->bucket_ring;
+
+  if (*l <= 0)
+  {
+    l1 = pLength(p1);
+    *l = l1;
+  }
+  else
+    l1 = *l;
+
+  if (m == NULL || p == NULL) return;
+
+#ifndef HAVE_PSEUDO_BUCKETS
+  kBucketMergeLm(bucket);
+  kbTest(bucket);
+  i = pLogLength(l1);
+
+  if ((i <= bucket->buckets_used) && (bucket->buckets[i] != NULL))
+  {
+    assume(pLength(bucket->buckets[i])==bucket->buckets_length[i]);
+//#ifdef USE_COEF_BUCKETS
+//     if(bucket->coef[i]!=NULL)
+//     {
+//       poly mult=p_Mult_mm(bucket->coef[i],m,r);
+//       bucket->coef[i]=NULL;
+//       p1 = p_Minus_mm_Mult_qq(bucket->buckets[i], mult, p1,
+//                               bucket->buckets_length[i], l1,
+//                             spNoether, r);
+//     }
+//     else
+//#endif
+    MULTIPLY_BUCKET(bucket,i);
+    p1 = p_Minus_mm_Mult_qq(bucket->buckets[i], m, p1,
+                            bucket->buckets_length[i], l1,
+                            spNoether, r);
+    l1 = bucket->buckets_length[i];
+    bucket->buckets[i] = NULL;
+    bucket->buckets_length[i] = 0;
+    i = pLogLength(l1);
+  }
+  else
+  {
+    pSetCoeff0(m, nNeg(pGetCoeff(m)));
+    if (spNoether != NULL)
+    {
+      l1 = -1;
+      p1 = r->p_Procs->pp_Mult_mm_Noether(p1, m, spNoether, l1, r, last);
+      i = pLogLength(l1);
+    }
+    else
+      p1 = r->p_Procs->pp_Mult_mm(p1, m, r, last);
+    pSetCoeff0(m, nNeg(pGetCoeff(m)));
+  }
+
+  while (bucket->buckets[i] != NULL)
+  {
+    //kbTest(bucket);
+    MULTIPLY_BUCKET(bucket,i);
+    p1 = p_Add_q(p1, bucket->buckets[i],
+                 l1, bucket->buckets_length[i], r);
+    bucket->buckets[i] = NULL;
+    bucket->buckets_length[i] = 0;
+    i = pLogLength(l1);
+  }
+
+  bucket->buckets[i] = p1;
+  bucket->buckets_length[i]=l1;
+  if (i >= bucket->buckets_used)
+    bucket->buckets_used = i;
+  else
+    kBucketAdjustBucketsUsed(bucket);
+#else // HAVE_PSEUDO_BUCKETS
+  bucket->p = p_Minus_mm_Mult_qq(bucket->p, m,  p,
+                               bucket->l, l1,
+                               spNoether, r);
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Bpoly == Bpoly + m*p; where m is a monom
+/// Does not destroy p and m
+/// assume (l <= 0 || pLength(p) == l)
+void kBucket_Plus_mm_Mult_pp(kBucket_pt bucket, poly m, poly p, int l)
+{
+  assume(l <= 0 || pLength(p) == l);
+  int i, l1;
+  poly p1 = p;
+  poly last;
+  ring r = bucket->bucket_ring;
+
+  if (l <= 0)
+  {
+    l1 = pLength(p1);
+    l = l1;
+  }
+  else
+    l1 = l;
+
+  if (m == NULL || p == NULL) return;
+
+  kBucketMergeLm(bucket);
+  kbTest(bucket);
+  i = pLogLength(l1);
+
+  if (i <= bucket->buckets_used && bucket->buckets[i] != NULL)
+  {
+    MULTIPLY_BUCKET(bucket,i);
+    p1 = p_Plus_mm_Mult_qq(bucket->buckets[i], m, p1,
+                           bucket->buckets_length[i], l1, r);
+    l1 = bucket->buckets_length[i];
+    bucket->buckets[i] = NULL;
+    bucket->buckets_length[i] = 0;
+    i = pLogLength(l1);
+  }
+  else
+  {
+    p1 = r->p_Procs->pp_Mult_mm(p1, m, r, last);
+  }
+
+  while (bucket->buckets[i] != NULL)
+  {
+    MULTIPLY_BUCKET(bucket,i);
+    p1 = p_Add_q(p1, bucket->buckets[i],
+                 l1, bucket->buckets_length[i], r);
+    bucket->buckets[i] = NULL;
+    bucket->buckets_length[i] = 0;
+    i = pLogLength(l1);
+  }
+
+  bucket->buckets[i] = p1;
+  bucket->buckets_length[i]=l1;
+  if (i >= bucket->buckets_used)
+    bucket->buckets_used = i;
+  else
+    kBucketAdjustBucketsUsed(bucket);
+
+  kbTest(bucket);
+}
+
+poly kBucket_ExtractLarger(kBucket_pt bucket, poly q, poly append)
+{
+  if (q == NULL) return append;
+  poly lm;
+  loop
+  {
+    lm = kBucketGetLm(bucket);
+    if (lm == NULL) return append;
+    if (p_LmCmp(lm, q, bucket->bucket_ring) == 1)
+    {
+      lm = kBucketExtractLm(bucket);
+      pNext(append) = lm;
+      pIter(append);
+    }
+    else
+    {
+      return append;
+    }
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Extract all monomials from bucket with component comp
+// Return as a polynomial *p with length *l
+// In other words, afterwards
+// Bpoly = Bpoly - (poly consisting of all monomials with component comp)
+// and components of monomials of *p are all 0
+//
+
+// Hmm... for now I'm too lazy to implement those independent of currRing
+// But better declare it extern than including polys.h
+extern void pTakeOutComp(poly *p, Exponent_t comp, poly *q, int *lq);
+void pDecrOrdTakeOutComp(poly *p, Exponent_t comp, Order_t order,
+                         poly *q, int *lq);
+
+void kBucketTakeOutComp(kBucket_pt bucket,
+                        Exponent_t comp,
+                        poly *r_p, int *l)
+{
+  poly p = NULL, q;
+  int i, lp = 0, lq;
+
+#ifndef HAVE_PSEUDO_BUCKETS
+  kBucketMergeLm(bucket);
+  for (i=1; i<=bucket->buckets_used; i++)
+  {
+    if (bucket->buckets[i] != NULL)
+    {
+      MULTIPLY_BUCKET(bucket,i);
+      pTakeOutComp(&(bucket->buckets[i]), comp, &q, &lq);
+      if (q != NULL)
+      {
+        assume(pLength(q) == lq);
+        bucket->buckets_length[i] -= lq;
+        assume(pLength(bucket->buckets[i]) == bucket->buckets_length[i]);
+        p = p_Add_q(p, q, lp, lq, bucket->bucket_ring);
+      }
+    }
+  }
+  kBucketAdjustBucketsUsed(bucket);
+#else
+  pTakeOutComp(&(bucket->p), comp, &p, &lp);
+  (bucket->l) -= lp;
+#endif
+  *r_p = p;
+  *l = lp;
+
+  kbTest(bucket);
+}
+
+void kBucketDecrOrdTakeOutComp(kBucket_pt bucket,
+                               Exponent_t comp, Order_t order,
+                               poly *r_p, int *l)
+{
+  poly p = NULL, q;
+  int i, lp = 0, lq;
+
+#ifndef HAVE_PSEUDO_BUCKETS
+  kBucketMergeLm(bucket);
+  for (i=1; i<=bucket->buckets_used; i++)
+  {
+    if (bucket->buckets[i] != NULL)
+    {
+      MULTIPLY_BUCKET(bucket,i);
+      pDecrOrdTakeOutComp(&(bucket->buckets[i]), comp, order, &q, &lq);
+      if (q != NULL)
+      {
+        bucket->buckets_length[i] -= lq;
+        p = p_Add_q(p, q, lp, lq, bucket->bucket_ring);
+      }
+    }
+  }
+  kBucketAdjustBucketsUsed(bucket);
+#else
+  pDecrOrdTakeOutComp(&(bucket->p), comp, order, &p, &lp);
+  (bucket->l) -= lp;
+#endif
+
+  *r_p = p;
+  *l = lp;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Reduction of Bpoly with a given poly
+//
+
+extern int ksCheckCoeff(number *a, number *b);
+
+number kBucketPolyRed(kBucket_pt bucket,
+                      poly p1, int l1,
+                      poly spNoether)
+{
+  assume(p1 != NULL &&
+         p_DivisibleBy(p1,  kBucketGetLm(bucket), bucket->bucket_ring));
+  assume(pLength(p1) == (int) l1);
+
+  poly a1 = pNext(p1), lm = kBucketExtractLm(bucket);
+  BOOLEAN reset_vec=FALSE;
+  number rn;
+
+  if(a1==NULL)
+  {
+    p_DeleteLm(&lm, bucket->bucket_ring);
+    return nInit(1);
+  }
+
+  if (! nIsOne(pGetCoeff(p1)))
+  {
+    number an = pGetCoeff(p1), bn = pGetCoeff(lm);
+    int ct = ksCheckCoeff(&an, &bn);
+    p_SetCoeff(lm, bn, bucket->bucket_ring);
+    if ((ct == 0) || (ct == 2)) kBucket_Mult_n(bucket, an);
+    rn = an;
+  }
+  else
+  {
+    rn = nInit(1);
+  }
+
+  if (p_GetComp(p1, bucket->bucket_ring) != p_GetComp(lm, bucket->bucket_ring))
+  {
+    p_SetCompP(a1, p_GetComp(lm, bucket->bucket_ring), bucket->bucket_ring);
+    reset_vec = TRUE;
+    p_SetComp(lm, p_GetComp(p1, bucket->bucket_ring), bucket->bucket_ring);
+    p_Setm(lm, bucket->bucket_ring);
+  }
+
+  p_ExpVectorSub(lm,p1, bucket->bucket_ring);
+  l1--;
+
+  kBucket_Minus_m_Mult_p(bucket, lm, a1, &l1, spNoether);
+
+  p_DeleteLm(&lm, bucket->bucket_ring);
+  if (reset_vec) p_SetCompP(a1, 0, bucket->bucket_ring);
+  kbTest(bucket);
+  return rn;
+}
+
+
Index: kernel/kbuckets.h
===================================================================
--- kernel/kbuckets.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/kbuckets.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,221 @@
+#ifndef KBUCKETS_H
+#define KBUCKETS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: kbuckets.h,v 1.1.1.1 2003-10-06 12:15:56 Singular Exp $ */
+#include "structs.h"
+#include "p_Procs.h"
+#include "pShallowCopyDelete.h"
+
+#define HAVE_COEF_BUCKETS
+
+/////////////////////////////////////////////////////////////////////////
+// configuration
+//
+
+// define to not really use the bucket feature
+// #define HAVE_PSEUDO_BUCKETS
+
+//////////////////////////////////////////////////////////////////////////
+// Creation/Destruction of buckets
+//
+kBucket_pt kBucketCreate(ring r = currRing);
+// only free memory allocated for bucket
+void kBucketDestroy(kBucket_pt *bucket);
+// frees polys/monomials in bucket and destroys bucket
+void kBucketDeleteAndDestroy(kBucket_pt *bucket);
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Convertion from/to Bpolys
+//
+
+// Converts p into a bucket poly (Bpoly) and destroys p
+// Assumes length <= 0 || pLength(p) == length
+void kBucketInit(kBucket_pt bucket, poly p, int length);
+
+// Converts Bpoly into a poly and clears bucket
+// i.e., afterwards Bpoly == 0
+void kBucketClear(kBucket_pt bucket, poly *p, int *length);
+inline poly kBucketClear(kBucket_pt bucket)
+{
+  int dummy;
+  poly p;
+  kBucketClear(bucket, &p, &dummy);
+  return p;
+}
+
+// Canonicalizes Bpoly, i.e. converts polys of buckets into one poly in
+// one bucket: Returns number of bucket into which it is canonicalized
+int kBucketCanonicalize(kBucket_pt bucket);
+
+/////////////////////////////////////////////////////////////////////////////
+// Gets leading monom of bucket, does NOT change Bpoly!!!!!
+// Returned monom is READ ONLY, i.e. no manipulations are allowed !!!!
+//
+inline const poly kBucketGetLm(kBucket_pt bucket);
+
+/////////////////////////////////////////////////////////////////////////////
+// Extracts lm of Bpoly, i.e. Bpoly is changed s.t.
+// Bpoly == Bpoly - Lm(Bpoly)
+//
+inline poly kBucketExtractLm(kBucket_pt bucket);
+
+/////////////////////////////////////////////////////////////////////////////
+// Sets Lm of Bpoly, i.e. Bpoly is changed s.t.
+// Bpoly = Bpoly + m
+// assumes that m is larger than all monomials of Bpoly
+void kBucketSetLm(kBucket_pt bucket, poly lm);
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Reduces Bpoly (say, q) with p, i.e.:
+// q = (Lc(p) / gcd(Lc(p), Lc(q)))*q - (Lc(q)/gcd(Lc(p),Lc(q)))*p*(Lm(q)/Lm(p))
+// Assumes p1 != NULL, Bpoly != NULL
+//         Lm(p1) divides Lm(Bpoly)
+//         pLength(p1) == l1
+// Returns: Lc(p) / gcd(Lc(p), Lc(q))
+number kBucketPolyRed(kBucket_pt bucket,
+                      poly p, int l,
+                      poly spNoether);
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Extract all monomials from bucket with component comp
+// Return as a polynomial *p with length *l
+// In other words, afterwards
+// Bpoly == Bpoly - (poly consisting of all monomials with component comp)
+// and components of monomials of *p are all 0
+
+void kBucketTakeOutComp(kBucket_pt bucket,
+                        Exponent_t comp,
+                        poly *p, int *l);
+
+// Here we only extract such monoms which have component == comp and
+// degree == order
+// ASSUME: monomial ordering is Order compatible, i.e., if m1, m2 Monoms then
+//         m1 >= m2 ==> pGetOrder(m1) >= pGetOrder(m2)
+void kBucketDecrOrdTakeOutComp(kBucket_pt bucket,
+                               Exponent_t comp, Order_t order,
+                               poly *p, int *l);
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Multiply Bucket by number ,i.e. Bpoly == n*Bpoly
+///
+void kBucket_Mult_n(kBucket_pt bucket, number n);
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Extract all monomials of bucket which are larger than q
+/// Append those to append, and return last monomial of append
+poly kBucket_ExtractLarger(kBucket_pt bucket, poly q, poly append);
+
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Add to Bucket a poly ,i.e. Bpoly == Bpoly + q
+///
+void kBucket_Add_q(kBucket_pt bucket, poly q, int* lq);
+
+// first, do ExtractLarger
+// then add q
+inline poly
+kBucket_ExtractLarger_Add_q(kBucket_pt bucket, poly append, poly q, int *lq)
+{
+  append = kBucket_ExtractLarger(bucket, q, append);
+  kBucket_Add_q(bucket, q, lq);
+  return append;
+}
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Bpoly == Bpoly - m*p; where m is a monom
+/// Does not destroy p and m
+/// assume (*l <= 0 || pLength(p) == *l)
+void kBucket_Minus_m_Mult_p(kBucket_pt bucket, poly m, poly p, int *l,
+                            poly spNother = NULL);
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Bpoly == Bpoly + m*p; where m is a monom
+/// Does not destroy p and m
+/// assume (l <= 0 || pLength(p) == l)
+void kBucket_Plus_mm_Mult_pp(kBucket_pt bucket, poly m, poly p, int l);
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// For changing the ring of the Bpoly to new_tailBin
+///
+void kBucketShallowCopyDelete(kBucket_pt bucket,
+                              ring new_tailRing, omBin new_tailBin,
+                              pShallowCopyDeleteProc p_shallow_copy_delete);
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Tests
+///
+///
+#ifdef KDEBUG
+BOOLEAN kbTest(kBucket_pt bucket);
+#else
+#define kbTest(bucket)  ((void)0)
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Bucket definition (should be no one elses business, though)
+///
+
+// define this if length of bucket polys are 2, 4, 8, etc
+// instead of 4, 16, 64 ... --
+// this seems to be less efficient, both, in theory and in practice
+// #define BUCKET_TWO_BASE
+#ifdef BUCKET_TWO_BASE
+#define MAX_BUCKET 28
+#else
+#define MAX_BUCKET 14 // suitable for polys up to a length of 4^14 = 2^28
+#endif
+
+class kBucket
+{
+public:
+#ifdef HAVE_PSEUDO_BUCKETS
+  poly p;
+  int l;
+#else
+  poly buckets[MAX_BUCKET + 1];        // polys in bucket
+#ifdef HAVE_COEF_BUCKETS
+  poly coef[MAX_BUCKET + 1];        // coeff of polys in bucket or NULL : 2..max
+#endif
+  int  buckets_length[MAX_BUCKET + 1]; // length if i-th poly
+  int buckets_used;                    // max number of used bucket
+#endif
+  ring bucket_ring;
+};
+
+inline void kBucketAdjustBucketsUsed(kBucket_pt bucket)
+{
+  while ( bucket->buckets_used > 0 &&
+          bucket->buckets[bucket->buckets_used] == NULL)
+    (bucket->buckets_used)--;
+}
+
+inline const poly kBucketGetLm(kBucket_pt bucket)
+{
+  if (bucket->buckets[0] == NULL)
+    bucket->bucket_ring->p_Procs->p_kBucketSetLm(bucket);
+  return bucket->buckets[0];
+}
+
+inline poly kBucketExtractLm(kBucket_pt bucket)
+{
+  poly lm = kBucketGetLm(bucket);
+  bucket->buckets[0] = NULL;
+  bucket->buckets_length[0] = 0;
+  return lm;
+}
+
+#endif /* KBUCKETS_H */
Index: kernel/khstd.cc
===================================================================
--- kernel/khstd.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/khstd.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,105 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: khstd.cc,v 1.1.1.1 2003-10-06 12:15:54 Singular Exp $ */
+/*
+* ABSTRACT:utils for hilbert driven kStd
+*/
+
+#include "mod2.h"
+#include "structs.h"
+#include "febase.h"
+#include "polys.h"
+#include "intvec.h"
+#include "kutil.h"
+#include "stairc.h"
+#include "kstd1.h"
+#include "khstd.h"
+
+
+/*2
+* compare the given hilbert series with the current one,
+* delete not needed pairs (if possible)
+*/
+void khCheck( ideal Q, intvec *w, intvec *hilb, int &eledeg, int &count,
+              kStrategy strat)
+  /* ideal S=strat->Shdl, poly p=strat->P.p */
+/*
+* compute the number eledeg of elements with a degree >= deg(p) going into kStd,
+* p is already in S and for all further q going into S yields deg(q) >= deg(p),
+* the real computation is only done if the degree has changed,
+* then we have eledeg == 0 on this degree and we make:
+*   - compute the Hilbert series newhilb from S
+*     (hilb is the final Hilbert series)
+*   - compute the eledeg from newhilb-hilb for the first degree deg with
+*     newhilb-hilb != 0
+*     (Remark: consider the Hilbert series with coeff. up to infinity)
+*   - clear the set L for degree < deg
+* the number count is only for statistics (in the caller initialise count = 0),
+* in order to get a first computation, initialise eledeg = 1 in the caller.
+* The weights w are needed in the module case, otherwise NULL.
+*/
+{
+  intvec *newhilb;
+  int deg,l,ln,mw;
+  pFDegProc degp;
+
+  eledeg--;
+  if (eledeg == 0)
+  {
+    degp=pFDeg;
+    // if weights for variables were given to std computations,
+    // then pFDeg == degp == kHomModDeg (see kStd)
+    if ((degp!=kModDeg) && (degp!=kHomModDeg)) degp=pTotaldegree;
+    // degp = pWDegree;
+    l = hilb->length()-1;
+    mw = (*hilb)[l];
+    newhilb = hHstdSeries(strat->Shdl,w,strat->kHomW,Q,strat->tailRing);
+    ln = newhilb->length()-1;
+    deg = degp(strat->P.p)-mw;
+    loop // compare the series in degree deg, try to increase deg -----------
+    {
+      if (deg < ln) // deg may be out of range
+      {
+        if (deg < l)
+          eledeg = (*newhilb)[deg]-(*hilb)[deg];
+        else
+          eledeg = (*newhilb)[deg];
+      }
+      else
+      {
+        if (deg < l)
+          eledeg = -(*hilb)[deg];
+        else // we have newhilb = hilb
+        {
+          while (strat->Ll>=0)
+          {
+            count++;
+            if(TEST_OPT_PROT)
+            {
+              PrintS("h");
+              mflush();
+            }
+            deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+          }
+          delete newhilb;
+          return;
+        }
+      }
+      if (eledeg != 0)
+        break;
+      deg++;
+    } /* loop */
+    delete newhilb;
+    while ((strat->Ll>=0) && (degp(strat->L[strat->Ll].p)-mw < deg)) // the essential step
+    {
+      count++;
+      if(TEST_OPT_PROT)
+      {
+        PrintS("h");
+        mflush();
+      }
+      deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+    }
+  }
+}
Index: kernel/khstd.h
===================================================================
--- kernel/khstd.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/khstd.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,17 @@
+#ifndef KHSTD_H
+#define KHSTD_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: khstd.h,v 1.1.1.1 2003-10-06 12:15:56 Singular Exp $ */
+/*
+* ABSTRACT:hilbert driven std
+*/
+
+#include "structs.h"
+
+void khCheck(ideal Q, intvec *w, intvec *hilb, int &eledeg, int &count,
+             kStrategy strat);
+                        /* ideal S=strat->Shdl, poly p=strat->P.p */
+
+#endif
Index: kernel/kmatrix.h
===================================================================
--- kernel/kmatrix.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/kmatrix.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,932 @@
+// ----------------------------------------------------------------------------
+//  kmatrix.h
+//  begin of file
+//  Stephan Endrass, endrass@mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#ifndef KMATRIX_H
+#define KMATRIX_H
+
+// ----------------------------------------------------------------------------
+//  template class for matrices with coefficients in the field  K
+//  K is a class representing elements of a field
+//  The implementation of  K  is expected to have overloaded
+//  the operators +, -, *, /, +=, -=, *= and /=.
+//  The expressions  (K)0  and (K)1  should cast to the  0  and  1  of  K.
+//  Additionally we use the following functions in class K:
+//
+//    member functions:
+//
+//      double  complexity( void );
+//
+//    friend functions:
+//
+//      friend  K   gcd( const K &a,const K &b );  // gcd(a,b)
+//      friend  K   gcd( K* a,int k );             // gcd(a[0],...,a[k-1])
+//
+//  The complexity function should return a measure indicating
+//  how complicated this number is in terms of memory usage
+//  and arithmetic operations. For a rational p/q, one could
+//  return max(|p|,|q|). This fuction is used for pivoting.
+//
+//  The gcd of two numbers a,b should be a number g such that
+//  the complexities of a/g and b/g are less or equal than those
+//  of a and b. For rationals p1/q1, p2/q2 one could return the
+//  quotient of integer gcd's gcd(p1,p2)/gcd(q1,q2).
+//
+// ----------------------------------------------------------------------------
+
+template<class K> class KMatrix
+{
+
+private:
+
+    K    *a;                                // the entries ot the matrix
+    int rows;                               // number of rows
+    int cols;                               // number of columns
+
+public:
+
+    KMatrix( );                             // init zero
+    KMatrix( const KMatrix& );              // copy constructor
+    KMatrix( int,int );                     // preallocate rows & columns
+
+    ~KMatrix( );                            // destructor
+
+    void    copy_delete ( void );           // delete associated memory
+    void    copy_new    ( int  );           // allocate associated memory
+    void    copy_zero   ( void );           // init zero
+    void    copy_unit   ( int );            // init as unit matrix
+    void    copy_shallow( KMatrix& );       // shallow copy
+    void    copy_deep   ( const KMatrix& ); // deep copy
+
+    K       get( int,int ) const;           // get an element
+    void    set( int,int,const K& );        // set an element
+
+    int     row_is_zero( int ) const;       // test if row is zero
+    int     column_is_zero( int ) const;    // test if column is zero
+
+    int     column_pivot( int,int ) const;
+
+    int     gausseliminate( void );         // Gauss elimination
+    int     rank( void ) const;             // compute the rank
+    int     solve( K**,int* );              // solve Ax=b from (A|b)
+
+    // elementary transformations
+
+    K       multiply_row( int,const K& );
+    K       add_rows( int,int,const K&,const K& );
+    int     swap_rows( int,int );
+    K       set_row_primitive( int );
+
+    int     is_quadratic( void ) const;
+    int     is_symmetric( void ) const;
+
+    K       determinant( void ) const;
+
+    #ifdef KMATRIX_DEBUG
+        void    test_row( int ) const;
+        void    test_col( int ) const;
+    #endif
+
+    #ifdef KMATRIX_PRINT
+        friend  ostream & operator << ( ostream&,const KMatrix& );
+    #endif
+};
+
+// ------------------------------------
+//  inline functions for class KMatrix
+// ------------------------------------
+
+// ----------------------------------------------------------------------------
+//  Delete memory associated to a  KMatrix
+// ----------------------------------------------------------------------------
+
+template<class K>
+    inline  void    KMatrix<K>::copy_delete( void )
+{
+    if( a != (K*)NULL && rows > 0 && cols > 0 ) delete [] a;
+    copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  Allocate memory associated to a  KMatrix
+// ----------------------------------------------------------------------------
+
+template<class K>
+    inline  void    KMatrix<K>::copy_new( int k )
+{
+    if( k > 0 )
+    {
+        a = new K[k];
+
+        #ifndef NDEBUG
+        if( a == (K*)NULL )
+        {
+            #ifdef KMATRIX_PRINT
+            #ifdef KMATRIX_IOSTREAM
+                cerr << "void KMatrix::copy_new( int k )";
+                cerr << ": no memory left ..." << endl;
+            #else
+                fprintf( stderr,"void KMatrix::copy_new( int k )" );
+                fprintf( stderr,": no memory left ...\n" );
+            #endif
+            #endif
+
+            exit( 1 );
+        }
+        #endif
+    }
+    else if( k == 0 )
+    {
+        a = (K*)NULL;
+    }
+    else
+    {
+        #ifdef KMATRIX_PRINT
+        #ifdef KMATRIX_IOSTREAM
+            cerr << "void KMatrix::copy_new( int k )";
+            cerr << ": k < 0 ..." << endl;
+        #else
+            fprintf( stderr,"void KMatrix::copy_new( int k )" );
+            fprintf( stderr,": k < 0 ...\n" );
+        #endif
+        #endif
+
+        exit( 1 );
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  Initialize a  KMatrix  with  0
+// ----------------------------------------------------------------------------
+
+template<class K>
+    inline  void    KMatrix<K>::copy_zero( void )
+{
+    a = (K*)NULL;
+    rows = cols = 0;
+}
+
+// ----------------------------------------------------------------------------
+//  Initialize a  KMatrix  with the unit matrix
+// ----------------------------------------------------------------------------
+
+template<class K>
+    inline  void    KMatrix<K>::copy_unit( int rank )
+{
+    int r,n=rank*rank;
+    copy_new( n );
+    rows = cols = rank;
+
+    for( r=0; r<n; a[r++]=(K)0 );
+
+    for( r=0; r<rows; r++ )
+    {
+        a[r*cols+r] = (K)1;
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  Shallow copy
+// ----------------------------------------------------------------------------
+
+template<class K>
+    inline  void    KMatrix<K>::copy_shallow( KMatrix &m )
+{
+    a = m.a;
+    rows = m.rows;
+    cols = m.cols;
+}
+
+// ----------------------------------------------------------------------------
+//  Deep copy
+// ----------------------------------------------------------------------------
+
+template<class K>
+    inline  void    KMatrix<K>::copy_deep( const KMatrix &m )
+{
+    if( m.a == (K*)NULL )
+    {
+        copy_zero( );
+    }
+    else
+    {
+        int n=m.rows*m.cols;
+        copy_new( n );
+        rows = m.rows;
+        cols = m.cols;
+
+        for( int i=0; i<n; i++ )
+        {
+            a[i] = m.a[i];
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  Zero constructor
+// ----------------------------------------------------------------------------
+
+template<class K>
+    inline  KMatrix<K>::KMatrix( )
+{
+    copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  Copy constructor
+// ----------------------------------------------------------------------------
+
+template<class K>
+    inline  KMatrix<K>::KMatrix( const KMatrix &m )
+{
+    copy_deep( m );
+}
+
+// ----------------------------------------------------------------------------
+//  Zero r by c matrix constructor
+// ----------------------------------------------------------------------------
+
+template<class K>
+    KMatrix<K>::KMatrix( int r,int c )
+{
+    int n = r*c;
+
+    copy_new( n );
+
+    rows = r;
+    cols = c;
+
+    for( int i=0; i<n; i++ )
+    {
+        a[i]=(K)0;
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  Destructor
+// ----------------------------------------------------------------------------
+
+template<class K>
+    KMatrix<K>::~KMatrix( )
+{
+    copy_delete( );
+}
+
+// -------------------------------------------------
+//  non-inline template functions for class KMatrix
+// -------------------------------------------------
+
+// ----------------------------------------------------------------------------
+//  Debugging functions
+// ----------------------------------------------------------------------------
+
+#ifdef KMATRIX_DEBUG
+
+template<class K>
+    void    KMatrix<K>::test_row( int r ) const
+{
+    if( r<0 || r>=rows )
+    {
+        #ifdef KMATRIX_PRINT
+        #ifdef KMATRIX_IOSTREAM
+            cerr << "KMatrix<K>::test_row( " << r << " )" << endl;
+            cerr << "    rows = " << rows << endl;
+            cerr << "    exiting...." << endl;
+        #else
+            fprintf( stderr,"KMatrix<K>::test_row( %d )\n",r );
+            fprintf( stderr,"    rows = %d\n",rows );
+            fprintf( stderr,"    exiting....\n" );
+        #endif
+        #endif
+
+        exit( 1 );
+    }
+}
+
+template<class K>
+    void    KMatrix<K>::test_col( int c ) const
+{
+    if( c<0 || c>=cols )
+    {
+        #ifdef KMATRIX_PRINT
+        #ifdef KMATRIX_IOSTREAM
+            cerr << "KMatrix<K>::test_col( " << c << " )" << endl;
+            cerr << "    cols = " << cols << endl;
+            cerr << "    exiting...." << endl;
+        #else
+            fprintf( stderr,"KMatrix<K>::test_col( %d )\n",c );
+            fprintf( stderr,"    cols = %d\n",cols );
+            fprintf( stderr,"    exiting....\n" );
+        #endif
+        #endif
+
+        exit( 1 );
+    }
+}
+
+#endif
+
+// ----------------------------------------------------------------------------
+//  get coefficient at row  r  and column  c
+//  return value: the coefficient
+// ----------------------------------------------------------------------------
+
+template<class K>
+    K    KMatrix<K>::get( int r,int c ) const
+{
+    #ifdef KMATRIX_DEBUG
+        test_row( r );
+        test_col( c );
+    #endif
+
+    return a[r*cols+c];
+}
+
+// ----------------------------------------------------------------------------
+//  sets coefficient at row  r  and column  c  to  value
+// ----------------------------------------------------------------------------
+
+template<class K>
+    void    KMatrix<K>::set( int r,int c,const K &value )
+{
+    #ifdef KMATRIX_DEBUG
+        test_row( r );
+        test_col( c );
+    #endif
+
+    a[r*cols+c] = value;
+}
+
+// ----------------------------------------------------------------------------
+//  interchanges the rows  r1  and  r2
+//  return value:  1 if r1==r2
+//  return value: -1 if r1!=r2
+//  caution: the determinant changes its sign by the return value
+// ----------------------------------------------------------------------------
+
+template<class K>
+    int     KMatrix<K>::swap_rows( int r1,int r2 )
+{
+    #ifdef KMATRIX_DEBUG
+        test_row( r1 );
+        test_row( r2 );
+    #endif
+
+    if( r1 == r2 ) return 1;
+
+    K   tmp;
+
+    for( int c=0; c<cols; c++ )
+    {
+        tmp          = a[r1*cols+c];
+        a[r1*cols+c] = a[r2*cols+c];
+        a[r2*cols+c] = tmp;
+    }
+
+    return -1;
+}
+
+// ----------------------------------------------------------------------------
+//  replaces row  r  by its multiple (row r)*factor
+//  return value: factor
+//  caution: the determinant changes by the return value
+// ----------------------------------------------------------------------------
+
+template<class K>
+    K    KMatrix<K>::multiply_row( int r,const K &factor )
+{
+    #ifdef KMATRIX_DEBUG
+        test_row( r );
+    #endif
+
+    int i_src = r*cols;
+
+    for( int i=0; i<cols; i++,i_src++ )
+    {
+        a[i_src] *= factor;
+    }
+    return  factor;
+}
+
+// ----------------------------------------------------------------------------
+//  replaces row  dest  by the linear combination
+//      (row src)*factor_src + (row dest)*factor_dest
+//  return value: factor_dest
+//  caution: the determinant changes by the return value
+// ----------------------------------------------------------------------------
+
+template<class K>
+    K   KMatrix<K>::add_rows(
+        int src,int dest,const K &factor_src,const K &factor_dest )
+{
+    #ifdef KMATRIX_DEBUG
+        test_row( src  );
+        test_row( dest );
+    #endif
+
+    int i;
+    int i_src  = src*cols;
+    int i_dest = dest*cols;
+
+    for( i=0; i<cols; i++,i_src++,i_dest++ )
+    {
+        a[i_dest] = a[i_src]*factor_src + a[i_dest]*factor_dest;
+    }
+
+    return factor_dest;
+}
+
+// ----------------------------------------------------------------------------
+//  test if row  r  is zero
+//  return value: TRUE  if zero
+//                FALSE if not zero
+// ----------------------------------------------------------------------------
+
+template<class K>
+    int     KMatrix<K>::row_is_zero( int r ) const
+{
+    #ifdef KMATRIX_DEBUG
+        test_row( r );
+    #endif
+
+    for( int c=0; c<cols; c++ )
+    {
+        if( a[r*cols+c] != (K)0 ) return FALSE;
+    }
+    return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+//  test if column  c  is zero
+//  return value: TRUE  if zero
+//                FALSE if not zero
+// ----------------------------------------------------------------------------
+
+template<class K>
+    int     KMatrix<K>::column_is_zero( int c ) const
+{
+    #ifdef KMATRIX_DEBUG
+        test_col( c );
+    #endif
+
+    for( int r=0; r<rows; r++ )
+    {
+        if( a[r*cols+c] != (K)0 ) return FALSE;
+    }
+    return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+//  find the element of column  c  if smallest nonzero absolute value
+//  consider only elements in row  r0  or below
+//  return value: the row of the element
+// ----------------------------------------------------------------------------
+
+template<class K>
+    int     KMatrix<K>::column_pivot( int r0,int c ) const
+{
+    #ifdef KMATRIX_DEBUG
+        test_row( r0 );
+        test_col( c  );
+    #endif
+
+    int r;
+    //  find first nonzero entry in column  c
+
+    for( r=r0; r<rows && a[r*cols+c]==(K)0; r++ );
+
+    if( r == rows )
+    {
+        //  column is zero
+
+        return -1;
+    }
+    else
+    {
+        double val     = a[r*cols+c].complexity( );
+        double val_new = 0.0;
+        int pivot   = r;
+
+        for( ; r<rows; r++ )
+        {
+            if( a[r*cols+c] != (K)0 &&
+                ( val_new = a[r*cols+c].complexity( ) ) < val )
+            {
+                val = val_new;
+                pivot = r;
+            }
+        }
+        return pivot;
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  divide row  r  by the gcd of all elements
+// ----------------------------------------------------------------------------
+
+template<class K>
+    K    KMatrix<K>::set_row_primitive( int r )
+{
+    #ifdef KMATRIX_DEBUG
+        test_row( r );
+    #endif
+
+    K   g = gcd( &(a[r*cols]),cols );
+
+    for( int c=0; c<cols; c++ )
+    {
+        a[r*cols+c] /= g;
+    }
+    return  g;
+}
+
+// ----------------------------------------------------------------------------
+//  convert the matrix to upper triangular form
+//  return value: rank of the matrix
+// ----------------------------------------------------------------------------
+
+template<class K>
+    int     KMatrix<K>::gausseliminate( void )
+{
+    int r,c,rank = 0;
+    K g;
+
+    //  make sure that the elements of each row have gcd=1
+    //  this is useful for pivoting
+
+    for( r=0; r<rows; r++ )
+    {
+        set_row_primitive( r );
+    }
+
+    //  search a pivoting element in each column
+    //  perform Gauss elimination
+
+    for( c=0; c<cols && rank<rows; c++ )
+    {
+        if( ( r = column_pivot( rank,c )) >= 0 )
+        {
+            swap_rows( rank,r );
+
+            for( r=rank+1; r<rows; r++ )
+            {
+                if( a[r*cols+c] != (K)0 )
+                {
+                    g = gcd( a[r*cols+c],a[rank*cols+c] );
+                    add_rows( rank,r,-a[r*cols+c]/g,a[rank*cols+c]/g );
+                    set_row_primitive( r );
+                }
+            }
+            rank++;
+        }
+    }
+    return rank;
+}
+
+// ----------------------------------------------------------------------------
+//  solve the linear system of equations given by
+//    (x1,...,xn,-1)*(*this) = 0
+//  return value: rank of the matrix
+//  k is set to the number of variables
+//  rat[0],...,rat[k-1] are set to the solutions
+// ----------------------------------------------------------------------------
+
+template<class K>
+    int     KMatrix<K>::solve( K **solution,int *k )
+{
+    int r,c,rank = 0;
+    K g;
+
+    // ----------------------------------------------------
+    //  make sure that the elements of each row have gcd=1
+    //  this is useful for pivoting
+    // ----------------------------------------------------
+
+    for( r=0; r<rows; r++ )
+    {
+        set_row_primitive( r );
+    }
+
+    // ------------------------------------------
+    //  search a pivoting element in each column
+    //  perform Gauss elimination
+    // ------------------------------------------
+
+    for( c=0; c<cols && rank < rows; c++ )
+    {
+        if( ( r = column_pivot( rank,c )) >= 0 )
+        {
+            swap_rows( rank,r );
+
+            for( r=0; r<rank; r++ )
+            {
+                if( a[r*cols+c] != (K)0 )
+                {
+                    g = gcd( a[r*cols+c],a[rank*cols+c] );
+                    add_rows( rank,r,-a[r*cols+c]/g,a[rank*cols+c]/g );
+                    set_row_primitive( r );
+                }
+            }
+
+            for( r=rank+1; r<rows; r++ )
+            {
+                if( a[r*cols+c] != (K)0 )
+                {
+                    g = gcd( a[r*cols+c],a[rank*cols+c] );
+                    add_rows( rank,r,-a[r*cols+c]/g,a[rank*cols+c]/g );
+                    set_row_primitive( r );
+                }
+            }
+
+            rank++;
+        }
+    }
+
+    if( rank < cols )
+    {
+        // ----------------------
+        //  equation is solvable
+        //  copy solutions
+        // ----------------------
+
+        *solution = new K[cols-1];
+        *k        = cols - 1;
+
+        for( c=0; c<cols-1; c++ )
+        {
+            (*solution)[c] = (K)0;
+        }
+
+        for( r=0; r<rows; r++ )
+        {
+            for( c=0; c<cols && a[r*cols+c] == (K)0; c++ );
+
+            if( c < cols-1 )
+            {
+                (*solution)[c] = ((K)a[(r+1)*cols-1])/a[r*cols+c];
+            }
+        }
+    }
+    else
+    {
+        // --------------------------
+        //  equation is not solvable
+        // --------------------------
+
+        *solution = (K*)NULL;
+        *k   = 0;
+    }
+
+    return rank;
+}
+
+// ----------------------------------------------------------------------------
+//  compute the rank of the matrix
+//  return value: rank of the matrix
+// ----------------------------------------------------------------------------
+
+template<class K>
+    int     KMatrix<K>::rank( void ) const
+{
+    KMatrix<K> dummy( *this );
+
+    return dummy.gausseliminate( );
+}
+
+// ----------------------------------------------------------------------------
+//  print the matrix
+//  return value: the output stream used
+// ----------------------------------------------------------------------------
+
+#ifdef KMATRIX_PRINT
+
+template<class K>
+    static
+        void    print_rational( ostream &s,int digits,const K &n )
+{
+    unsigned int num = digits - n.length( );
+
+    for( unsigned int i=0; i < num; i++ )
+    {
+        #ifdef KMATRIX_IOSTREAM
+            s << " ";
+        #else
+            fprintf( stdout," " );
+        #endif
+    }
+
+    s << n;
+}
+
+template<class K>
+    ostream &    operator << ( ostream &s,const KMatrix<K> &m )
+{
+    int i,r,c,digits=0,tmp;
+
+    for( i=0; i<m.rows*m.cols; i++ )
+    {
+        tmp = m.a[i].length( );
+
+        if( tmp > digits ) digits = tmp;
+    }
+
+    for( r=0; r<m.rows; r++ )
+    {
+        if( m.rows == 1 )
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << "<";
+            #else
+                fprintf( stdout,"<" );
+            #endif
+        }
+        else if( r == 0 )
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << "/";
+            #else
+                fprintf( stdout,"/" );
+            #endif
+        }
+        else if( r == m.rows - 1 )
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << "\\";
+            #else
+                fprintf( stdout,"\\" );
+            #endif
+        }
+        else
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << "|";
+            #else
+                fprintf( stdout,"|" );
+            #endif
+        }
+
+        for( c=0; c<m.cols; c++ )
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << " ";
+            #else
+                fprintf( stdout," " );
+            #endif
+
+            print_rational( s,digits,m.a[r*m.cols+c] );
+        }
+
+        if( m.rows == 1 )
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << " >";
+            #else
+                fprintf( stdout," >" );
+            #endif
+        }
+        else if( r == 0 )
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << " \\" << endl;
+            #else
+                fprintf( stdout," \\\n" );
+            #endif
+        }
+        else if( r == m.rows - 1 )
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << " /";
+            #else
+                fprintf( stdout," /" );
+            #endif
+        }
+        else
+        {
+            #ifdef KMATRIX_IOSTREAM
+                s << " |" << endl;
+            #else
+                fprintf( stdout," |\n" );
+            #endif
+        }
+    }
+    return s;
+}
+
+#endif
+
+// ----------------------------------------------------------------------------
+//  test if the matrix is quadratic
+//  return value: TRUE or FALSE
+// ----------------------------------------------------------------------------
+
+template<class K>
+    int     KMatrix<K>::is_quadratic( void ) const
+{
+    return ( rows == cols ? TRUE : FALSE );
+}
+
+// ----------------------------------------------------------------------------
+//  test if the matrix is symmetric
+//  return value: TRUE or FALSE
+// ----------------------------------------------------------------------------
+
+template<class K>
+     int     KMatrix<K>::is_symmetric( void ) const
+{
+    if( is_quadratic( ) )
+    {
+        int r,c;
+
+        for( r=1; r<rows; r++ )
+        {
+            for( c=0; c<r; c++ )
+            {
+                if( a[r*cols+c] != a[c*cols+r] )
+                {
+                    return  FALSE;
+                }
+            }
+        }
+        return  TRUE;
+    }
+    else
+    {
+        return  FALSE;
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  compute the determinant
+//  return value: the determinant
+// ----------------------------------------------------------------------------
+
+template<class K> K KMatrix<K>::determinant( void ) const
+{
+    if( !is_quadratic( ) )
+    {
+        return 0;
+    }
+
+    KMatrix<K> dummy( *this );
+
+    int r,c,rank = 0;
+    K g;
+    K frank,fr;
+    K det = 1;
+
+    //  make sure that the elements of each row have gcd=1
+    //  this is useful for pivoting
+
+    for( r=0; r<dummy.rows; r++ )
+    {
+        det *= dummy.set_row_primitive( r );
+    }
+
+    //  search a pivoting element in each column
+    //  perform Gauss elimination
+
+    for( c=0; c<cols && rank<dummy.rows; c++ )
+    {
+        if( ( r = dummy.column_pivot( rank,c )) >= 0 )
+        {
+            det *= dummy.swap_rows( rank,r );
+
+            for( r=rank+1; r<dummy.rows; r++ )
+            {
+                if( dummy.a[r*cols+c] != (K)0 )
+                {
+                    g = gcd( dummy.a[r*cols+c],dummy.a[rank*cols+c] );
+
+                    frank = -dummy.a[r*cols+c]/g;
+                    fr    = dummy.a[rank*cols+c]/g;
+
+                    det /= dummy.add_rows( rank,r,frank,fr );
+                    det *= dummy.set_row_primitive( r );
+                }
+            }
+            rank++;
+        }
+    }
+
+    if( rank != dummy.rows )
+    {
+        return 0;
+    }
+
+    for( r=0; r<dummy.rows; r++ )
+    {
+        det *= dummy.a[r*cols+r];
+    }
+
+    return  det;
+}
+
+#endif /* KMATRIX_H */
+
+// ----------------------------------------------------------------------------
+//  kmatrix.h
+//  end of file
+// ----------------------------------------------------------------------------
Index: kernel/kspoly.cc
===================================================================
--- kernel/kspoly.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/kspoly.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,485 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: kspoly.cc,v 1.1.1.1 2003-10-06 12:15:56 Singular Exp $ */
+/*
+*  ABSTRACT -  Routines for Spoly creation and reductions
+*/
+
+// #define PDEBUG 2
+#include "mod2.h"
+#include "kutil.h"
+#include "numbers.h"
+#include "p_polys.h"
+#include "p_Procs.h"
+#include "gring.h"
+
+#ifdef KDEBUG
+int red_count = 0;
+int create_count = 0;
+// define this if reductions are reported on TEST_OPT_DEBUG
+// #define TEST_OPT_DEBUG_RED
+#endif
+
+/***************************************************************
+ *
+ * Reduces PR with PW
+ * Assumes PR != NULL, PW != NULL, Lm(PW) divides Lm(PR)
+ *
+ ***************************************************************/
+int ksReducePoly(LObject* PR,
+                 TObject* PW,
+                 poly spNoether,
+                 number *coef,
+                 kStrategy strat)
+{
+#ifdef KDEBUG
+  red_count++;
+#ifdef TEST_OPT_DEBUG_RED
+  if (TEST_OPT_DEBUG)
+  {
+    Print("Red %d:", red_count); PR->wrp(); Print(" with:");
+    PW->wrp();
+  }
+#endif
+#endif
+  int ret = 0;
+  ring tailRing = PR->tailRing;
+  kTest_L(PR);
+  kTest_T(PW);
+
+  poly p1 = PR->GetLmTailRing();
+  poly p2 = PW->GetLmTailRing();
+  poly t2 = pNext(p2), lm = p1;
+  assume(p1 != NULL && p2 != NULL);
+  p_CheckPolyRing(p1, tailRing);
+  p_CheckPolyRing(p2, tailRing);
+
+  pAssume1(p2 != NULL && p1 != NULL &&
+           p_DivisibleBy(p2,  p1, tailRing));
+
+  pAssume1(p_GetComp(p1, tailRing) == p_GetComp(p2, tailRing) ||
+           (p_GetComp(p2, tailRing) == 0 &&
+            p_MaxComp(pNext(p2),tailRing) == 0));
+
+  if (rIsPluralRing(currRing))
+  {
+    // for the time being: we know currRing==strat->tailRing
+    // no exp-bound checking needed 
+    // (only needed if exp-bound(tailring)<exp-b(currRing))
+    number c;
+    if (PR->bucket!=NULL)  nc_kBucketPolyRed(PR->bucket, p2,&c);
+    else 
+    {
+      poly _p = (PR->t_p != NULL ? PR->t_p : PR->p);
+      assume(_p != NULL);
+      nc_PolyPolyRed(_p, p2,&c);
+      if (PR->t_p!=NULL) PR->t_p=_p; else PR->p=_p;
+      PR->pLength=pLength(_p);
+    }
+    if (coef!=NULL) *coef=c;
+    else nDelete(&c);
+    return 0;
+  }
+
+  if (t2==NULL)
+  {
+    PR->LmDeleteAndIter();
+    if (coef != NULL) *coef = n_Init(1, tailRing);
+    return 0;
+  }
+
+  p_ExpVectorSub(lm, p2, tailRing);
+
+  if (tailRing != currRing)
+  {
+    // check that reduction does not violate exp bound
+    while (PW->max != NULL && !p_LmExpVectorAddIsOk(lm, PW->max, tailRing))
+    {
+      // undo changes of lm
+      p_ExpVectorAdd(lm, p2, tailRing);
+      if (strat == NULL) return 2;
+      if (! kStratChangeTailRing(strat, PR, PW)) return -1;
+      tailRing = strat->tailRing;
+      p1 = PR->GetLmTailRing();
+      p2 = PW->GetLmTailRing();
+      t2 = pNext(p2);
+      lm = p1;
+      p_ExpVectorSub(lm, p2, tailRing);
+      ret = 1;
+    }
+  }
+
+  // take care of coef buisness
+  if (! n_IsOne(pGetCoeff(p2), tailRing))
+  {
+    number bn = pGetCoeff(lm);
+    number an = pGetCoeff(p2);
+    int ct = ksCheckCoeff(&an, &bn);
+    p_SetCoeff(lm, bn,tailRing);
+    if ((ct == 0) || (ct == 2))
+      PR->Tail_Mult_nn(an);
+    if (coef != NULL) *coef = an;
+    else n_Delete(&an, tailRing);
+  }
+  else
+  {
+    if (coef != NULL) *coef = n_Init(1, tailRing);
+  }
+
+
+  // and finally,
+  PR->Tail_Minus_mm_Mult_qq(lm, t2, PW->GetpLength() - 1, spNoether);
+  PR->LmDeleteAndIter();
+#if defined(KDEBUG) && defined(TEST_OPT_DEBUG_RED)
+  if (TEST_OPT_DEBUG)
+  {
+    Print(" to: "); PR->wrp(); Print("\n");
+  }
+#endif
+  return ret;
+}
+
+/***************************************************************
+ *
+ * Creates S-Poly of p1 and p2
+ *
+ *
+ ***************************************************************/
+void ksCreateSpoly(LObject* Pair,   poly spNoether,
+                   int use_buckets, ring tailRing,
+                   poly m1, poly m2, TObject** R)
+{
+#ifdef KDEBUG
+  create_count++;
+#endif
+  kTest_L(Pair);
+  poly p1 = Pair->p1;
+  poly p2 = Pair->p2;
+  poly last;
+  Pair->tailRing = tailRing;
+
+  assume(p1 != NULL);
+  assume(p2 != NULL);
+  assume(tailRing != NULL);
+
+  poly a1 = pNext(p1), a2 = pNext(p2);
+  number lc1 = pGetCoeff(p1), lc2 = pGetCoeff(p2);
+  int co=0, ct = ksCheckCoeff(&lc1, &lc2);
+
+  int l1=0, l2=0;
+
+  if (p_GetComp(p1, currRing)!=p_GetComp(p2, currRing))
+  {
+    if (p_GetComp(p1, currRing)==0)
+    {
+      co=1;
+      p_SetCompP(p1,p_GetComp(p2, currRing), currRing, tailRing);
+    }
+    else
+    {
+      co=2;
+      p_SetCompP(p2, p_GetComp(p1, currRing), currRing, tailRing);
+    }
+  }
+
+  // get m1 = LCM(LM(p1), LM(p2))/LM(p1)
+  //     m2 = LCM(LM(p1), LM(p2))/LM(p2)
+  if (m1 == NULL)
+    k_GetLeadTerms(p1, p2, currRing, m1, m2, tailRing);
+
+  pSetCoeff0(m1, lc2);
+  pSetCoeff0(m2, lc1);  // and now, m1 * LT(p1) == m2 * LT(p2)
+
+  if (R != NULL)
+  {
+    l1 = (R[Pair->i_r1])->GetpLength() - 1;
+    l2 = (R[Pair->i_r2])->GetpLength() - 1;
+  }
+
+  // get m2 * a2
+  if (spNoether != NULL)
+  {
+    l2 = -1;
+    a2 = tailRing->p_Procs->pp_Mult_mm_Noether(a2, m2, spNoether, l2, tailRing,last);
+    assume(l2 == pLength(a2));
+  }
+  else
+    a2 = tailRing->p_Procs->pp_Mult_mm(a2, m2, tailRing,last);
+  Pair->SetLmTail(m2, a2, l2, use_buckets, tailRing, last);
+
+  // get m2*a2 - m1*a1
+  Pair->Tail_Minus_mm_Mult_qq(m1, a1, l1, spNoether);
+
+  // Clean-up time
+  Pair->LmDeleteAndIter();
+  p_LmDelete(m1, tailRing);
+
+  if (co != 0)
+  {
+    if (co==1)
+    {
+      p_SetCompP(p1,0, currRing, tailRing);
+    }
+    else
+    {
+      p_SetCompP(p2,0, currRing, tailRing);
+    }
+  }
+}
+
+int ksReducePolyTail(LObject* PR, TObject* PW, poly Current, poly spNoether)
+{
+  BOOLEAN ret;
+  number coef;
+  poly Lp =     PR->GetLmCurrRing();
+  poly Save =   PW->GetLmCurrRing();
+
+  kTest_L(PR);
+  kTest_T(PW);
+  pAssume(pIsMonomOf(Lp, Current));
+
+  assume(Lp != NULL && Current != NULL && pNext(Current) != NULL);
+  assume(PR->bucket == NULL);
+
+  LObject Red(pNext(Current), PR->tailRing);
+  TObject With(PW, Lp == Save);
+
+  pAssume(!pHaveCommonMonoms(Red.p, With.p));
+  ret = ksReducePoly(&Red, &With, spNoether, &coef);
+
+  if (!ret)
+  {
+    if (! n_IsOne(coef, currRing))
+    {
+      pNext(Current) = NULL;
+      if (Current == PR->p && PR->t_p != NULL)
+        pNext(PR->t_p) = NULL;
+      PR->Mult_nn(coef);
+    }
+
+    n_Delete(&coef, currRing);
+    pNext(Current) = Red.GetLmTailRing();
+    if (Current == PR->p && PR->t_p != NULL)
+      pNext(PR->t_p) = pNext(Current);
+  }
+
+  if (Lp == Save)
+    With.Delete();
+  return ret;
+}
+
+/***************************************************************
+ *
+ * Auxillary Routines
+ *
+ *
+ ***************************************************************/
+
+/*
+* input - output: a, b
+* returns:
+*   a := a/gcd(a,b), b := b/gcd(a,b)
+*   and return value
+*       0  ->  a != 1,  b != 1
+*       1  ->  a == 1,  b != 1
+*       2  ->  a != 1,  b == 1
+*       3  ->  a == 1,  b == 1
+*   this value is used to control the spolys
+*/
+int ksCheckCoeff(number *a, number *b)
+{
+  int c = 0;
+  number an = *a, bn = *b;
+  nTest(an);
+  nTest(bn);
+
+  number cn = nGcd(an, bn, currRing);
+
+  if(nIsOne(cn))
+  {
+    an = nCopy(an);
+    bn = nCopy(bn);
+  }
+  else
+  {
+    an = nIntDiv(an, cn);
+    bn = nIntDiv(bn, cn);
+  }
+  nDelete(&cn);
+  if (nIsOne(an))
+  {
+    c = 1;
+  }
+  if (nIsOne(bn))
+  {
+    c += 2;
+  }
+  *a = an;
+  *b = bn;
+  return c;
+}
+
+/*2
+* creates the leading term of the S-polynomial of p1 and p2
+* do not destroy p1 and p2
+* remarks:
+*   1. the coefficient is 0 (nNew)
+*   2. pNext is undefined
+*/
+//static void bbb() { int i=0; }
+poly ksCreateShortSpoly(poly p1, poly p2, ring tailRing)
+{
+  poly a1 = pNext(p1), a2 = pNext(p2);
+  Exponent_t c1=p_GetComp(p1, currRing),c2=p_GetComp(p2, currRing);
+  Exponent_t c;
+  poly m1,m2;
+  number t1,t2;
+  int cm,i;
+  BOOLEAN equal;
+
+  if (a1==NULL)
+  {
+    if(a2!=NULL)
+    {
+      m2=p_Init(currRing);
+x2:
+      for (i = pVariables; i; i--)
+      {
+        c = p_GetExpDiff(p1, p2,i, currRing);
+        if (c>0)
+        {
+          p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)),currRing);
+        }
+        else
+        {
+          p_SetExp(m2,i,p_GetExp(a2,i,tailRing),currRing);
+        }
+      }
+      if ((c1==c2)||(c2!=0))
+      {
+        p_SetComp(m2,p_GetComp(a2,tailRing), currRing);
+      }
+      else
+      {
+        p_SetComp(m2,c1,currRing);
+      }
+      p_Setm(m2, currRing);
+      nNew(&(pGetCoeff(m2)));
+      return m2;
+    }
+    else
+      return NULL;
+  }
+  if (a2==NULL)
+  {
+    m1=p_Init(currRing);
+x1:
+    for (i = pVariables; i; i--)
+    {
+      c = p_GetExpDiff(p2, p1,i,currRing);
+      if (c>0)
+      {
+        p_SetExp(m1,i,(c+p_GetExp(a1,i, tailRing)),currRing);
+      }
+      else
+      {
+        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
+      }
+    }
+    if ((c1==c2)||(c1!=0))
+    {
+      p_SetComp(m1,p_GetComp(a1,tailRing),currRing);
+    }
+    else
+    {
+      p_SetComp(m1,c2,currRing);
+    }
+    p_Setm(m1, currRing);
+    nNew(&(pGetCoeff(m1)));
+    return m1;
+  }
+  m1 = p_Init(currRing);
+  m2 = p_Init(currRing);
+  for(;;)
+  {
+    for (i = pVariables; i; i--)
+    {
+      c = p_GetExpDiff(p1, p2,i,currRing);
+      if (c > 0)
+      {
+        p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)), currRing);
+        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
+      }
+      else
+      {
+        p_SetExp(m1,i,(p_GetExp(a1,i,tailRing)-c), currRing);
+        p_SetExp(m2,i,p_GetExp(a2,i, tailRing), currRing);
+      }
+    }
+    if(c1==c2)
+    {
+      p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
+      p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
+    }
+    else
+    {
+      if(c1!=0)
+      {
+        p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
+        p_SetComp(m2,c1, currRing);
+      }
+      else
+      {
+        p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
+        p_SetComp(m1,c2, currRing);
+      }
+    }
+    p_Setm(m1,currRing);
+    p_Setm(m2,currRing);
+    cm = p_LmCmp(m1, m2,currRing);
+    if (cm!=0)
+    {
+      if(cm==1)
+      {
+        p_LmFree(m2,currRing);
+        nNew(&(pGetCoeff(m1)));
+        return m1;
+      }
+      else
+      {
+        p_LmFree(m1,currRing);
+        nNew(&(pGetCoeff(m2)));
+        return m2;
+      }
+    }
+    t1 = nMult(pGetCoeff(a2),pGetCoeff(p1));
+    t2 = nMult(pGetCoeff(a1),pGetCoeff(p2));
+    equal = nEqual(t1,t2);
+    nDelete(&t2);
+    nDelete(&t1);
+    if (!equal)
+    {
+      p_LmFree(m2,currRing);
+      nNew(&(pGetCoeff(m1)));
+      return m1;
+    }
+    pIter(a1);
+    pIter(a2);
+    if (a2==NULL)
+    {
+      p_LmFree(m2,currRing);
+      if (a1==NULL)
+      {
+        p_LmFree(m1,currRing);
+        return NULL;
+      }
+      goto x1;
+    }
+    if (a1==NULL)
+    {
+      p_LmFree(m1,currRing);
+      goto x2;
+    }
+  }
+}
Index: kernel/kstd1.cc
===================================================================
--- kernel/kstd1.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/kstd1.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,2008 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: kstd1.cc,v 1.1.1.1 2003-10-06 12:15:54 Singular Exp $ */
+/*
+* ABSTRACT:
+*/
+
+// define if buckets should be used
+#define MORA_USE_BUCKETS
+
+// define if tailrings should be used
+#define HAVE_TAIL_RING
+
+#include "mod2.h"
+#include "structs.h"
+#include "omalloc.h"
+#include "kutil.h"
+#include "kInline.cc"
+#include "polys.h"
+#include "febase.h"
+#include "kstd1.h"
+#include "khstd.h"
+#include "stairc.h"
+#include "weight.h"
+//#include "cntrlc.h"
+#include "intvec.h"
+#include "ideals.h"
+#include "../Singular/ipid.h"
+#include "timer.h"
+
+//#include "ipprint.h"
+
+/* the list of all options which give a warning by test */
+BITSET kOptions=Sy_bit(OPT_PROT)           /*  0 */
+                |Sy_bit(OPT_REDSB)         /*  1 */
+                |Sy_bit(OPT_NOT_SUGAR)     /*  3 */
+                |Sy_bit(OPT_INTERRUPT)     /*  4 */
+                |Sy_bit(OPT_SUGARCRIT)     /*  5 */
+                |Sy_bit(OPT_REDTHROUGH)
+                |Sy_bit(OPT_OLDSTD)
+                |Sy_bit(OPT_FASTHC)        /* 10 */
+                |Sy_bit(OPT_KEEPVARS)      /* 21 */
+                |Sy_bit(OPT_INTSTRATEGY)   /* 26 */
+                |Sy_bit(OPT_INFREDTAIL)    /* 28 */
+                |Sy_bit(OPT_NOTREGULARITY) /* 30 */
+                |Sy_bit(OPT_WEIGHTM);      /* 31 */
+
+/* the list of all options which may be used by option and test */
+BITSET validOpts=Sy_bit(0)
+                |Sy_bit(1)
+                |Sy_bit(2) // obachman 10/00: replaced by notBucket
+                |Sy_bit(3)
+                |Sy_bit(4)
+                |Sy_bit(5)
+                |Sy_bit(6)
+//                |Sy_bit(7) obachman 11/00 tossed: 12/00 used for redThrough
+  |Sy_bit(OPT_REDTHROUGH)
+//                |Sy_bit(8) obachman 11/00 tossed
+                |Sy_bit(9)
+                |Sy_bit(10)
+                |Sy_bit(11)
+                |Sy_bit(12)
+                |Sy_bit(13)
+                |Sy_bit(14)
+                |Sy_bit(15)
+                |Sy_bit(16)
+                |Sy_bit(17)
+                |Sy_bit(18)
+                |Sy_bit(19)
+//                |Sy_bit(20) obachman 11/00 tossed: 12/00 used for redOldStd
+  |Sy_bit(OPT_OLDSTD)
+                |Sy_bit(21)
+                |Sy_bit(22)
+                /*|Sy_bit(23)*/
+                /*|Sy_bit(24)*/
+                |Sy_bit(OPT_REDTAIL)
+                |Sy_bit(OPT_INTSTRATEGY)
+                |Sy_bit(27)
+                |Sy_bit(28)
+                |Sy_bit(29)
+                |Sy_bit(30)
+                |Sy_bit(31);
+
+//static BOOLEAN posInLOldFlag;
+           /*FALSE, if posInL == posInL10*/
+// returns TRUE if mora should use buckets, false otherwise
+static BOOLEAN kMoraUseBucket(kStrategy strat);
+
+static void kOptimizeLDeg(pLDegProc ldeg, kStrategy strat)
+{
+  if (strat->ak == 0 && !rIsSyzIndexRing(currRing))
+    strat->length_pLength = TRUE;
+  else
+    strat->length_pLength = FALSE;
+
+  if ((ldeg == pLDeg0c && !rIsSyzIndexRing(currRing)) ||
+      (ldeg == pLDeg0 && strat->ak == 0))
+  {
+    strat->LDegLast = TRUE;
+  }
+  else
+  {
+    strat->LDegLast = FALSE;
+  }
+}
+
+
+static int doRed (LObject* h, TObject* with,BOOLEAN intoT,kStrategy strat)
+{
+  poly hp;
+  int ret;
+#if KDEBUG > 0
+  kTest_L(h);
+  kTest_T(with);
+#endif
+  // Hmmm ... why do we do this -- polys from T should already be normalized
+  if (!TEST_OPT_INTSTRATEGY)
+    with->pNorm();
+#ifdef KDEBUG
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("reduce ");h->wrp();PrintS(" with ");with->wrp();PrintLn();
+  }
+#endif
+  if (intoT)
+  {
+    // need to do it exacly like this: otherwise
+    // we might get errors
+    LObject L= *h;
+    L.Copy();
+    h->GetP();
+    h->SetLength(strat->length_pLength);
+    ret = ksReducePoly(&L, with, strat->kNoetherTail(), NULL, strat);
+    if (ret)
+    {
+      if (ret < 0) return ret;
+      if (h->tailRing != strat->tailRing)
+        h->ShallowCopyDelete(strat->tailRing,
+                             pGetShallowCopyDeleteProc(h->tailRing,
+                                                       strat->tailRing));
+    }
+    enterT(*h,strat);
+    *h = L;
+  }
+  else
+    ret = ksReducePoly(h, with, strat->kNoetherTail(), NULL, strat);
+#ifdef KDEBUG
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("to ");h->wrp();PrintLn();
+  }
+#endif
+  return ret;
+}
+
+int redEcart (LObject* h,kStrategy strat)
+{
+  poly pi;
+  int i,at,reddeg,d,ei,li,ii;
+  int j = 0;
+  int pass = 0;
+
+  d = h->GetpFDeg()+ h->ecart;
+  reddeg = strat->LazyDegree+d;
+  h->SetShortExpVector();
+  loop
+  {
+    j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, h);
+    if (j < 0)
+    {
+      if (strat->honey) h->SetLength(strat->length_pLength);
+      return 1;
+    }
+
+    ei = strat->T[j].ecart;
+    ii = j;
+
+    if (ei > h->ecart && ii < strat->tl)
+    {
+      li = strat->T[j].length;
+      // the polynomial to reduce with (up to the moment) is;
+      // pi with ecart ei and length li
+      // look for one with smaller ecart
+      i = j;
+      loop
+      {
+        /*- takes the first possible with respect to ecart -*/
+        i++;
+#if 1
+        if (i > strat->tl) break;
+        if ((strat->T[i].ecart < ei || (strat->T[i].ecart == ei &&
+                                        strat->T[i].length < li))
+            &&
+            p_LmShortDivisibleBy(strat->T[i].GetLmTailRing(), strat->sevT[i], h->GetLmTailRing(), ~h->sev, strat->tailRing))
+#else
+          j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, h, i);
+        if (j < 0) break;
+        i = j;
+        if (strat->T[i].ecart < ei || (strat->T[i].ecart == ei &&
+                                        strat->T[i].length < li))
+#endif
+        {
+          // the polynomial to reduce with is now
+          ii = i;
+          ei = strat->T[i].ecart;
+          if (ei <= h->ecart) break;
+          li = strat->T[i].length;
+        }
+      }
+    }
+
+    // end of search: have to reduce with pi
+    if (ei > h->ecart)
+    {
+      // It is not possible to reduce h with smaller ecart;
+      // if possible h goes to the lazy-set L,i.e
+      // if its position in L would be not the last one
+      strat->fromT = TRUE;
+      if (!K_TEST_OPT_REDTHROUGH && strat->Ll >= 0) /*- L is not empty -*/
+      {
+        h->SetLmCurrRing();
+        if (strat->honey && strat->posInLDependsOnLength)
+          h->SetLength(strat->length_pLength);
+        assume(h->FDeg == h->pFDeg());
+        at = strat->posInL(strat->L,strat->Ll,h,strat);
+        if (at <= strat->Ll)
+        {
+          /*- h will not become the next element to reduce -*/
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+#ifdef KDEBUG
+          if (TEST_OPT_DEBUG) Print(" ecart too big; -> L%d\n",at);
+#endif
+          h->Clear();
+          strat->fromT = FALSE;
+          return -1;
+        }
+      }
+    }
+
+    // now we finally can reduce
+    doRed(h,&(strat->T[ii]),strat->fromT,strat);
+    strat->fromT=FALSE;
+
+    // are we done ???
+    if (h->IsNull())
+    {
+      if (h->lcm!=NULL) pLmFree(h->lcm);
+      h->Clear();
+      return 0;
+    }
+
+    // NO!
+    h->SetShortExpVector();
+    h->SetpFDeg();
+    if (strat->honey)
+    {
+      if (ei <= h->ecart)
+        h->ecart = d-h->GetpFDeg();
+      else
+        h->ecart = d-h->GetpFDeg()+ei-h->ecart;
+    }
+    else
+      // this has the side effect of setting h->length
+      h->ecart = h->pLDeg(strat->LDegLast) - h->GetpFDeg();
+
+    if (strat->syzComp!=0)
+    {
+      if ((strat->syzComp>0) && (h->Comp() > strat->syzComp))
+      {
+        assume(h->MinComp() > strat->syzComp);
+        if (strat->honey) h->SetLength();
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG) PrintS(" > syzComp\n");
+#endif
+        return -2;
+      }
+    }
+    /*- try to reduce the s-polynomial -*/
+    pass++;
+    d = h->GetpFDeg()+h->ecart;
+    /*
+     *test whether the polynomial should go to the lazyset L
+     *-if the degree jumps
+     *-if the number of pre-defined reductions jumps
+     */
+    if (!K_TEST_OPT_REDTHROUGH && (strat->Ll >= 0)
+        && ((d >= reddeg) || (pass > strat->LazyPass)))
+    {
+      h->SetLmCurrRing();
+      if (strat->honey && strat->posInLDependsOnLength)
+        h->SetLength(strat->length_pLength);
+      assume(h->FDeg == h->pFDeg());
+      at = strat->posInL(strat->L,strat->Ll,h,strat);
+      if (at <= strat->Ll)
+      {
+        if (kFindDivisibleByInS(strat->S, strat->sevS, strat->sl, h) < 0)
+        {
+          if (strat->honey && !strat->posInLDependsOnLength)
+            h->SetLength(strat->length_pLength);
+          return 1;
+        }
+        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG) Print(" degree jumped; ->L%d\n",at);
+#endif
+        h->Clear();
+        return -1;
+      }
+    }
+    else if ((TEST_OPT_PROT) && (strat->Ll < 0) && (d >= reddeg))
+    {
+      Print(".%d",d);mflush();
+      reddeg = d+1;
+    }
+  }
+}
+
+/*2
+*reduces h with elements from T choosing  the first possible
+* element in t with respect to the given pDivisibleBy
+*/
+int redFirst (LObject* h,kStrategy strat)
+{
+  if (h->IsNull()) return 0;
+
+  int at, reddeg,d;
+  int pass = 0;
+  int j = 0;
+
+  if (! strat->homog)
+  {
+    d = h->GetpFDeg() + h->ecart;
+    reddeg = strat->LazyDegree+d;
+  }
+  h->SetShortExpVector();
+  while (1)
+  {
+    j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, h);
+    if (j < 0)
+    {
+      h->SetDegStuffReturnLDeg(strat->LDegLast);
+      return 1;
+    }
+
+    if (!TEST_OPT_INTSTRATEGY)
+      strat->T[j].pNorm();
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("reduce ");
+      h->wrp();
+      PrintS(" with ");
+      strat->T[j].wrp();
+    }
+#endif
+    ksReducePoly(h, &(strat->T[j]), strat->kNoetherTail(), NULL, strat);
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS(" to ");
+      wrp(h->p);
+      PrintLn();
+    }
+#endif
+    if (h->IsNull())
+    {
+      if (h->lcm!=NULL) pLmFree(h->lcm);
+      h->Clear();
+      return 0;
+    }
+    h->SetShortExpVector();
+
+    if ((strat->syzComp!=0) && !strat->honey)
+    {
+      if ((strat->syzComp>0) &&
+          (h->Comp() > strat->syzComp))
+      {
+        assume(h->MinComp() > strat->syzComp);
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG) PrintS(" > syzComp\n");
+#endif
+        if (strat->homog)
+          h->SetDegStuffReturnLDeg(strat->LDegLast);
+        return -2;
+      }
+    }
+    if (!strat->homog)
+    {
+      if (!K_TEST_OPT_OLDSTD && strat->honey)
+      {
+        h->SetpFDeg();
+        if (strat->T[j].ecart <= h->ecart)
+          h->ecart = d - h->GetpFDeg();
+        else
+          h->ecart = d - h->GetpFDeg() + strat->T[j].ecart - h->ecart;
+
+        d = h->GetpFDeg() + h->ecart;
+      }
+      else
+        d = h->SetDegStuffReturnLDeg(strat->LDegLast);
+      /*- try to reduce the s-polynomial -*/
+      pass++;
+      /*
+       *test whether the polynomial should go to the lazyset L
+       *-if the degree jumps
+       *-if the number of pre-defined reductions jumps
+       */
+      if (!K_TEST_OPT_REDTHROUGH && (strat->Ll >= 0)
+          && ((d >= reddeg) || (pass > strat->LazyPass)))
+      {
+        h->SetLmCurrRing();
+        if (strat->posInLDependsOnLength)
+          h->SetLength(strat->length_pLength);
+        at = strat->posInL(strat->L,strat->Ll,h,strat);
+        if (at <= strat->Ll)
+        {
+          if (kFindDivisibleByInS(strat->S, strat->sevS, strat->sl, h) < 0)
+            return 1;
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+#ifdef KDEBUG
+          if (TEST_OPT_DEBUG) Print(" degree jumped; ->L%d\n",at);
+#endif
+          h->Clear();
+          return -1;
+        }
+      }
+      if ((TEST_OPT_PROT) && (strat->Ll < 0) && (d >= reddeg))
+      {
+        reddeg = d+1;
+        Print(".%d",d);mflush();
+      }
+    }
+  }
+}
+
+/*2
+* reduces h with elements from T choosing first possible
+* element in T with respect to the given ecart
+* used for computing normal forms outside kStd
+*/
+static poly redMoraNF (poly h,kStrategy strat, int flag)
+{
+  LObject H;
+  H.p = h;
+  int j = 0;
+  int z = 10;
+  int o = H.SetpFDeg();
+  H.ecart = pLDeg(H.p,&H.length)-o;
+  if ((flag & 2) == 0) cancelunit(&H);
+  H.sev = pGetShortExpVector(H.p);
+  unsigned long not_sev = ~ H.sev;
+  loop
+  {
+    if (j > strat->tl)
+    {
+      return H.p;
+    }
+    if (TEST_V_DEG_STOP)
+    {
+      if (kModDeg(H.p)>Kstd1_deg) pDeleteLm(&H.p);
+      if (H.p==NULL) return NULL;
+    }
+    if (p_LmShortDivisibleBy(strat->T[j].GetLmTailRing(), strat->sevT[j], H.GetLmTailRing(), not_sev, strat->tailRing))
+    {
+      //if (strat->interpt) test_int_std(strat->kIdeal);
+      /*- remember the found T-poly -*/
+      poly pi = strat->T[j].p;
+      int ei = strat->T[j].ecart;
+      int li = strat->T[j].length;
+      int ii = j;
+      /*
+      * the polynomial to reduce with (up to the moment) is;
+      * pi with ecart ei and length li
+      */
+      loop
+      {
+        /*- look for a better one with respect to ecart -*/
+        /*- stop, if the ecart is small enough (<=ecart(H)) -*/
+        j++;
+        if (j > strat->tl) break;
+        if (ei <= H.ecart) break;
+        if (((strat->T[j].ecart < ei)
+          || ((strat->T[j].ecart == ei)
+        && (strat->T[j].length < li)))
+        && pLmShortDivisibleBy(strat->T[j].p,strat->sevT[j], H.p, not_sev))
+        {
+          /*
+          * the polynomial to reduce with is now;
+          */
+          pi = strat->T[j].p;
+          ei = strat->T[j].ecart;
+          li = strat->T[j].length;
+          ii = j;
+        }
+      }
+      /*
+      * end of search: have to reduce with pi
+      */
+      z++;
+      if (z>10)
+      {
+        pNormalize(H.p);
+        z=0;
+      }
+      if ((ei > H.ecart) && (!strat->kHEdgeFound))
+      {
+        /*
+        * It is not possible to reduce h with smaller ecart;
+        * we have to reduce with bad ecart: H has to enter in T
+        */
+        doRed(&H,&(strat->T[ii]),TRUE,strat);
+        if (H.p == NULL)
+          return NULL;
+      }
+      else
+      {
+        /*
+        * we reduce with good ecart, h need not to be put to T
+        */
+        doRed(&H,&(strat->T[ii]),FALSE,strat);
+        if (H.p == NULL)
+          return NULL;
+      }
+      /*- try to reduce the s-polynomial -*/
+      o = H.SetpFDeg();
+      if ((flag &2 ) == 0) cancelunit(&H);
+      H.ecart = pLDeg(H.p,&(H.length))-o;
+      j = 0;
+      H.sev = pGetShortExpVector(H.p);
+      not_sev = ~ H.sev;
+    }
+    else
+    {
+      j++;
+    }
+  }
+}
+
+/*2
+*reorders  L with respect to posInL
+*/
+void reorderL(kStrategy strat)
+{
+  int i,j,at;
+  LObject p;
+
+  for (i=1; i<=strat->Ll; i++)
+  {
+    at = strat->posInL(strat->L,i-1,&(strat->L[i]),strat);
+    if (at != i)
+    {
+      p = strat->L[i];
+      for (j=i-1; j>=at; j--) strat->L[j+1] = strat->L[j];
+      strat->L[at] = p;
+    }
+  }
+}
+
+/*2
+*reorders  T with respect to length
+*/
+void reorderT(kStrategy strat)
+{
+  int i,j,at;
+  TObject p;
+  unsigned long sev;
+
+
+  for (i=1; i<=strat->tl; i++)
+  {
+    if (strat->T[i-1].length > strat->T[i].length)
+    {
+      p = strat->T[i];
+      sev = strat->sevT[i];
+      at = i-1;
+      loop
+      {
+        at--;
+        if (at < 0) break;
+        if (strat->T[i].length > strat->T[at].length) break;
+      }
+      for (j = i-1; j>at; j--)
+      {
+        strat->T[j+1]=strat->T[j];
+        strat->sevT[j+1]=strat->sevT[j];
+        strat->R[strat->T[j+1].i_r] = &(strat->T[j+1]);
+      }
+      strat->T[at+1]=p;
+      strat->sevT[at+1] = sev;
+      strat->R[p.i_r] = &(strat->T[at+1]);
+    }
+  }
+}
+
+/*2
+*looks whether exactly pVariables-1 axis are used
+*returns last != 0 in this case
+*last is the (first) unused axis
+*/
+void missingAxis (int* last,kStrategy strat)
+{
+  int   i = 0;
+  int   k = 0;
+
+  *last = 0;
+  if (!currRing->MixedOrder)
+  {
+    loop
+    {
+      i++;
+      if (i > pVariables) break;
+      if (strat->NotUsedAxis[i])
+      {
+        *last = i;
+        k++;
+      }
+      if (k>1)
+      {
+        *last = 0;
+        break;
+      }
+    }
+  }
+}
+
+/*2
+*last is the only non used axis, it looks
+*for a monomial in p being a pure power of this
+*variable and returns TRUE in this case
+*(*length) gives the length between the pure power and the leading term
+*(should be minimal)
+*/
+BOOLEAN hasPurePower (const poly p,int last, int *length,kStrategy strat)
+{
+  poly h;
+  int i;
+
+  if (pNext(p) == strat->tail)
+    return FALSE;
+  pp_Test(p, currRing, strat->tailRing);
+  if (strat->ak <= 0 || p_MinComp(p, currRing, strat->tailRing) == strat->ak)
+  {
+    i = p_IsPurePower(p, currRing);
+    if (i == last)
+    {
+      *length = 0;
+      return TRUE;
+    }
+    *length = 1;
+    h = pNext(p);
+    while (h != NULL)
+    {
+      i = p_IsPurePower(h, strat->tailRing);
+      if (i==last) return TRUE;
+      (*length)++;
+      pIter(h);
+    }
+  }
+  return FALSE;
+}
+
+BOOLEAN hasPurePower (LObject *L,int last, int *length,kStrategy strat)
+{
+  if (L->bucket != NULL)
+  {
+    poly p = L->CanonicalizeP();
+    BOOLEAN ret = hasPurePower(p, last, length, strat);
+    pNext(p) = NULL;
+    return ret;
+  }
+  else
+  {
+    return hasPurePower(L->p, last, length, strat);
+  }
+}
+
+/*2
+* looks up the position of polynomial p in L
+* in the case of looking for the pure powers
+*/
+int posInL10 (const LSet set,const int length, LObject* p,const kStrategy strat)
+{
+  int j,dp,dL;
+
+  if (length<0) return 0;
+  if (hasPurePower(p,strat->lastAxis,&dp,strat))
+  {
+    int op= p->GetpFDeg() +p->ecart;
+    for (j=length; j>=0; j--)
+    {
+      if (!hasPurePower(&(set[j]),strat->lastAxis,&dL,strat))
+        return j+1;
+      if (dp < dL)
+        return j+1;
+      if ((dp == dL)
+          && (set[j].GetpFDeg()+set[j].ecart >= op))
+        return j+1;
+    }
+  }
+  j=length;
+  loop
+  {
+    if (j<0) break;
+    if (!hasPurePower(&(set[j]),strat->lastAxis,&dL,strat)) break;
+    j--;
+  }
+  return strat->posInLOld(set,j,p,strat);
+}
+
+
+/*2
+* computes the s-polynomials L[ ].p in L
+*/
+void updateL(kStrategy strat)
+{
+  LObject p;
+  int dL;
+  int j=strat->Ll;
+  loop
+  {
+    if (j<0) break;
+    if (hasPurePower(&(strat->L[j]),strat->lastAxis,&dL,strat))
+    {
+      p=strat->L[strat->Ll];
+      strat->L[strat->Ll]=strat->L[j];
+      strat->L[j]=p;
+      break;
+    }
+    j--;
+  }
+  if (j<0)
+  {
+    j=strat->Ll;
+    loop
+    {
+      if (j<0) break;
+      if (pNext(strat->L[j].p) == strat->tail)
+      {
+        pLmFree(strat->L[j].p);    /*deletes the short spoly and computes*/
+        strat->L[j].p = NULL;
+        poly m1 = NULL, m2 = NULL;
+        // check that spoly creation is ok
+        while (strat->tailRing != currRing &&
+               !kCheckSpolyCreation(&(strat->L[j]), strat, m1, m2))
+        {
+          assume(m1 == NULL && m2 == NULL);
+          // if not, change to a ring where exponents are at least
+          // large enough
+          kStratChangeTailRing(strat);
+        }
+        /* create the real one */
+        ksCreateSpoly(&(strat->L[j]), strat->kNoetherTail(), FALSE,
+                      strat->tailRing, m1, m2, strat->R);
+
+        strat->L[j].SetLmCurrRing();
+        if (!strat->honey)
+          strat->initEcart(&strat->L[j]);
+        else
+          strat->L[j].SetLength(strat->length_pLength);
+
+        BOOLEAN pp = hasPurePower(&(strat->L[j]),strat->lastAxis,&dL,strat);
+
+        if (strat->use_buckets) strat->L[j].PrepareRed(TRUE);
+
+        if (pp)
+        {
+          p=strat->L[strat->Ll];
+          strat->L[strat->Ll]=strat->L[j];
+          strat->L[j]=p;
+          break;
+        }
+      }
+      j--;
+    }
+  }
+}
+
+/*2
+* computes the s-polynomials L[ ].p in L and
+* cuts elements in L above noether
+*/
+void updateLHC(kStrategy strat)
+{
+  int i = 0;
+  kTest_TS(strat);
+  while (i <= strat->Ll)
+  {
+    if (pNext(strat->L[i].p) == strat->tail)
+    {
+       /*- deletes the int spoly and computes -*/
+      if (pLmCmp(strat->L[i].p,strat->kNoether) == -1)
+      {
+        pLmFree(strat->L[i].p);
+        strat->L[i].p = NULL;
+      }
+      else
+      {
+        pLmFree(strat->L[i].p);
+        strat->L[i].p = NULL;
+        poly m1 = NULL, m2 = NULL;
+        // check that spoly creation is ok
+        while (strat->tailRing != currRing &&
+               !kCheckSpolyCreation(&(strat->L[i]), strat, m1, m2))
+        {
+          assume(m1 == NULL && m2 == NULL);
+          // if not, change to a ring where exponents are at least
+          // large enough
+          kStratChangeTailRing(strat);
+        }
+        /* create the real one */
+        ksCreateSpoly(&(strat->L[i]), strat->kNoetherTail(), FALSE,
+                      strat->tailRing, m1, m2, strat->R);
+        if (! strat->L[i].IsNull())
+        {
+          strat->L[i].SetLmCurrRing();
+          strat->L[i].SetpFDeg();
+          strat->L[i].ecart
+            = strat->L[i].pLDeg(strat->LDegLast) - strat->L[i].GetpFDeg();
+          if (strat->use_buckets) strat->L[i].PrepareRed(TRUE);
+        }
+      }
+    }
+    else
+      deleteHC(&(strat->L[i]), strat);
+   if (strat->L[i].IsNull())
+      deleteInL(strat->L,&strat->Ll,i,strat);
+    else
+    {
+#ifdef KDEBUG
+      kTest_L(&(strat->L[i]), strat->tailRing, TRUE, i, strat->T, strat->tl);
+#endif
+      i++;
+    }
+  }
+  kTest_TS(strat);
+}
+
+/*2
+* cuts in T above strat->kNoether and tries to cancel a unit
+*/
+void updateT(kStrategy strat)
+{
+  int i = 0;
+  LObject p;
+
+  while (i <= strat->tl)
+  {
+    p = strat->T[i];
+    deleteHC(&p,strat, TRUE);
+    /*- tries to cancel a unit: -*/
+    cancelunit(&p);
+    if (p.p != strat->T[i].p)
+    {
+      strat->sevT[i] = pGetShortExpVector(p.p);
+      p.SetpFDeg();
+    }
+    strat->T[i] = p;
+    i++;
+  }
+}
+
+/*2
+* arranges red, pos and T if strat->kHEdgeFound (first time)
+*/
+void firstUpdate(kStrategy strat)
+{
+  if (strat->update)
+  {
+    kTest_TS(strat);
+    strat->update = (strat->tl == -1);
+    if (TEST_OPT_WEIGHTM)
+    {
+      pRestoreDegProcs(pFDegOld, pLDegOld);
+      if (strat->tailRing != currRing)
+      {
+        strat->tailRing->pFDeg = strat->pOrigFDeg_TailRing;
+        strat->tailRing->pLDeg = strat->pOrigLDeg_TailRing;
+      }
+      int i;
+      for (i=strat->Ll; i>=0; i--)
+      {
+        strat->L[i].SetpFDeg();
+      }
+      for (i=strat->tl; i>=0; i--)
+      {
+        strat->T[i].SetpFDeg();
+      }
+      if (ecartWeights)
+      {
+        omFreeSize((ADDRESS)ecartWeights,(pVariables+1)*sizeof(short));
+        ecartWeights=NULL;
+      }
+    }
+    if (TEST_OPT_FASTHC)
+    {
+      strat->posInL = strat->posInLOld;
+      strat->lastAxis = 0;
+    }
+    if (BTEST1(27))
+      return;
+    strat->red = redFirst;
+    strat->use_buckets = kMoraUseBucket(strat);
+    updateT(strat);
+    strat->posInT = posInT2;
+    reorderT(strat);
+  }
+  kTest_TS(strat);
+}
+
+/*2
+*-puts p to the standardbasis s at position at
+*-reduces the tail of p if TEST_OPT_REDTAIL
+*-tries to cancel a unit
+*-HEckeTest
+*  if TRUE
+*  - decides about reduction-strategies
+*  - computes noether
+*  - stops computation if BTEST1(27)
+*  - cuts the tails of the polynomials
+*    in s,t and the elements in L above noether
+*    and cancels units if possible
+*  - reorders s,L
+*/
+void enterSMora (LObject p,int atS,kStrategy strat, int atR = -1)
+{
+  int i;
+  enterSBba(p, atS, strat, atR);
+  if (TEST_OPT_DEBUG)
+  {
+    Print("new s%d:",atS);
+    wrp(p.p);
+    PrintLn();
+  }
+  if ((!strat->kHEdgeFound) || (strat->kNoether!=NULL)) HEckeTest(p.p,strat);
+  if (strat->kHEdgeFound)
+  {
+    if (newHEdge(strat->S,strat))
+    {
+      firstUpdate(strat);
+      if (BTEST1(27))
+        return;
+      /*- cuts elements in L above noether and reorders L -*/
+      updateLHC(strat);
+      /*- reorders L with respect to posInL -*/
+      reorderL(strat);
+    }
+  }
+  else if (strat->kNoether!=NULL)
+    strat->kHEdgeFound = TRUE;
+  else if (TEST_OPT_FASTHC)
+  {
+    if (strat->posInLOldFlag)
+    {
+      missingAxis(&strat->lastAxis,strat);
+      if (strat->lastAxis)
+      {
+        strat->posInLOld = strat->posInL;
+        strat->posInLOldFlag = FALSE;
+        strat->posInL = posInL10;
+        strat->posInLDependsOnLength = TRUE;
+        updateL(strat);
+        reorderL(strat);
+      }
+    }
+    else if (strat->lastAxis)
+      updateL(strat);
+  }
+}
+
+/*2
+*-puts p to the standardbasis s at position at
+*-HEckeTest
+*  if TRUE
+*  - computes noether
+*/
+void enterSMoraNF (LObject p, int atS,kStrategy strat, int atR = -1)
+{
+  int i;
+
+  enterSBba(p, atS, strat, atR);
+  if ((!strat->kHEdgeFound) || (strat->kNoether!=NULL)) HEckeTest(p.p,strat);
+  if (strat->kHEdgeFound)
+    newHEdge(strat->S,strat);
+  else if (strat->kNoether!=NULL)
+    strat->kHEdgeFound = TRUE;
+}
+
+void initBba(ideal F,kStrategy strat)
+{
+  int i;
+  idhdl h;
+ /* setting global variables ------------------- */
+  strat->enterS = enterSBba;
+  if (strat->honey)
+    strat->red = redHoney;
+  else if (pLexOrder && !strat->homog)
+    strat->red = redLazy;
+  else
+    strat->red = redHomog;
+  if (pLexOrder && strat->honey)
+    strat->initEcart = initEcartNormal;
+  else
+    strat->initEcart = initEcartBBA;
+  if (strat->honey)
+    strat->initEcartPair = initEcartPairMora;
+  else
+    strat->initEcartPair = initEcartPairBba;
+  strat->kIdeal = NULL;
+  //if (strat->ak==0) strat->kIdeal->rtyp=IDEAL_CMD;
+  //else              strat->kIdeal->rtyp=MODUL_CMD;
+  //strat->kIdeal->data=(void *)strat->Shdl;
+  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
+  {
+    //interred  machen   Aenderung
+    pFDegOld=pFDeg;
+    pLDegOld=pLDeg;
+    h=ggetid("ecart");
+    if ((h!=NULL) /*&& (IDTYP(h)==INTVEC_CMD)*/)
+    {
+      ecartWeights=iv2array(IDINTVEC(h));
+    }
+    else
+    {
+      ecartWeights=(short *)omAlloc((pVariables+1)*sizeof(short));
+      /*uses automatic computation of the ecartWeights to set them*/
+      kEcartWeights(F->m,IDELEMS(F)-1,ecartWeights);
+    }
+    pRestoreDegProcs(totaldegreeWecart, maxdegreeWecart);
+    if (TEST_OPT_PROT)
+    {
+      for(i=1; i<=pVariables; i++)
+        Print(" %d",ecartWeights[i]);
+      PrintLn();
+      mflush();
+    }
+  }
+}
+
+void initMora(ideal F,kStrategy strat)
+{
+  int i,j;
+  idhdl h;
+
+  strat->NotUsedAxis = (BOOLEAN *)omAlloc((pVariables+1)*sizeof(BOOLEAN));
+  for (j=pVariables; j>0; j--) strat->NotUsedAxis[j] = TRUE;
+  strat->enterS = enterSMora;
+  strat->initEcartPair = initEcartPairMora; /*- ecart approximation -*/
+  strat->posInLOld = strat->posInL;
+  strat->posInLOldFlag = TRUE;
+  strat->initEcart = initEcartNormal;
+  strat->kHEdgeFound = ppNoether != NULL;
+  if ( strat->kHEdgeFound )
+     strat->kNoether = pCopy(ppNoether);
+  else if (strat->kHEdgeFound || strat->homog)
+    strat->red = redFirst;  /*take the first possible in T*/
+  else
+    strat->red = redEcart;/*take the first possible in under ecart-restriction*/
+  if (strat->kHEdgeFound)
+  {
+    strat->HCord = pFDeg(ppNoether)+1;
+    strat->posInT = posInT2;
+  }
+  else
+  {
+    strat->HCord = 32000;/*- very large -*/
+  }
+  /*reads the ecartWeights used for Graebes method from the
+   *intvec ecart and set ecartWeights
+   */
+  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
+  {
+    //interred  machen   Aenderung
+    pFDegOld=pFDeg;
+    pLDegOld=pLDeg;
+    h=ggetid("ecart");
+    if ((h!=NULL) /*&& (IDTYP(h)==INTVEC_CMD)*/)
+    {
+      ecartWeights=iv2array(IDINTVEC(h));
+    }
+    else
+    {
+      ecartWeights=(short *)omAlloc((pVariables+1)*sizeof(short));
+      /*uses automatic computation of the ecartWeights to set them*/
+      kEcartWeights(F->m,IDELEMS(F)-1,ecartWeights);
+    }
+
+    pSetDegProcs(totaldegreeWecart, maxdegreeWecart);
+    if (TEST_OPT_PROT)
+    {
+      for(i=1; i<=pVariables; i++)
+        Print(" %d",ecartWeights[i]);
+      PrintLn();
+      mflush();
+    }
+  }
+  kOptimizeLDeg(pLDeg, strat);
+}
+
+#ifdef HAVE_ASSUME
+static int mora_count = 0;
+static int mora_loop_count;
+#endif
+
+ideal mora (ideal F, ideal Q,intvec *w,intvec *hilb,kStrategy strat)
+{
+#ifdef HAVE_ASSUME
+  mora_count++;
+  mora_loop_count = 0;
+#endif
+#ifdef KDEBUG
+  om_Opts.MinTrack = 5;
+#endif
+  int srmax;
+  int lrmax = 0;
+  int olddeg = 0;
+  int reduc = 0;
+  int red_result = 1;
+  int hilbeledeg=1,hilbcount=0;
+
+  strat->update = TRUE;
+  /*- setting global variables ------------------- -*/
+  initBuchMoraCrit(strat);
+  initHilbCrit(F,Q,&hilb,strat);
+  initMora(F,strat);
+  initBuchMoraPos(strat);
+  /*Shdl=*/initBuchMora(F,Q,strat);
+  if (TEST_OPT_FASTHC) missingAxis(&strat->lastAxis,strat);
+  /*updateS in initBuchMora has Hecketest
+  * and could have put strat->kHEdgdeFound FALSE*/
+  if (ppNoether!=NULL)
+  {
+    strat->kHEdgeFound = TRUE;
+  }
+  if (strat->kHEdgeFound && strat->update)
+  {
+    firstUpdate(strat);
+    updateLHC(strat);
+    reorderL(strat);
+  }
+  if (TEST_OPT_FASTHC && (strat->lastAxis) && strat->posInLOldFlag)
+  {
+    strat->posInLOld = strat->posInL;
+    strat->posInLOldFlag = FALSE;
+    strat->posInL = posInL10;
+    updateL(strat);
+    reorderL(strat);
+  }
+  srmax = strat->sl;
+  kTest_TS(strat);
+  strat->use_buckets = kMoraUseBucket(strat);
+  /*- compute-------------------------------------------*/
+
+#ifdef HAVE_TAIL_RING
+//  if (strat->homog && strat->red == redFirst)
+    kStratInitChangeTailRing(strat);
+#endif
+
+  while (strat->Ll >= 0)
+  {
+#ifdef HAVE_ASSUME
+    mora_loop_count++;
+#endif
+    if (lrmax< strat->Ll) lrmax=strat->Ll; /*stat*/
+    //test_int_std(strat->kIdeal);
+    if (TEST_OPT_DEBUG) messageSets(strat);
+    if (TEST_OPT_DEGBOUND
+    && (strat->L[strat->Ll].ecart+strat->L[strat->Ll].GetpFDeg()> Kstd1_deg))
+    {
+      /*
+      * stops computation if
+      * - 24 (degBound)
+      *   && upper degree is bigger than Kstd1_deg
+      */
+      while ((strat->Ll >= 0)
+        && (strat->L[strat->Ll].ecart+strat->L[strat->Ll].GetpFDeg()> Kstd1_deg)
+        && (strat->L[strat->Ll].p1!=NULL) && (strat->L[strat->Ll].p2!=NULL))
+      {
+        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+        //if (TEST_OPT_PROT)
+        //{
+        //   PrintS("D"); mflush();
+        //}
+      }
+      if (strat->Ll<0) break;
+    }
+    strat->P = strat->L[strat->Ll];/*- picks the last element from the lazyset L -*/
+    if (strat->Ll==0) strat->interpt=TRUE;
+    strat->Ll--;
+
+    // create the real Spoly
+    if (pNext(strat->P.p) == strat->tail)
+    {
+      /*- deletes the short spoly and computes -*/
+      pLmFree(strat->P.p);
+      strat->P.p = NULL;
+      poly m1 = NULL, m2 = NULL;
+      // check that spoly creation is ok
+      while (strat->tailRing != currRing &&
+             !kCheckSpolyCreation(&(strat->P), strat, m1, m2))
+      {
+        assume(m1 == NULL && m2 == NULL);
+        // if not, change to a ring where exponents are large enough
+        kStratChangeTailRing(strat);
+      }
+      /* create the real one */
+      ksCreateSpoly(&(strat->P), strat->kNoetherTail(), strat->use_buckets,
+                    strat->tailRing, m1, m2, strat->R);
+      if (!strat->use_buckets)
+        strat->P.SetLength(strat->length_pLength);
+    }
+    else if (strat->P.p1 == NULL)
+    {
+      // for input polys, prepare reduction (buckets !)
+      strat->P.SetLength(strat->length_pLength);
+      strat->P.PrepareRed(strat->use_buckets);
+    }
+
+    if (!strat->P.IsNull())
+    {
+      // might be NULL from noether !!!
+      if (TEST_OPT_PROT)
+        message(strat->P.ecart+strat->P.GetpFDeg(),&olddeg,&reduc,strat, red_result);
+      // reduce
+      red_result = strat->red(&strat->P,strat);
+    }
+
+    if (! strat->P.IsNull())
+    {
+      strat->P.GetP();
+      // statistics
+      if (TEST_OPT_PROT) PrintS("s");
+      // normalization
+      if (!TEST_OPT_INTSTRATEGY)
+        strat->P.pNorm();
+      // tailreduction
+      strat->P.p = redtail(&(strat->P),strat->sl,strat);
+      // set ecart -- might have changed because of tail reductions
+      if ((!strat->noTailReduction) && (!strat->honey))
+        strat->initEcart(&strat->P);
+      // for char 0, clear denominators
+      if (TEST_OPT_INTSTRATEGY)
+        strat->P.pCleardenom();
+      // cancel unit
+      cancelunit(&strat->P);
+
+      // put in T
+      enterT(strat->P,strat);
+      // build new pairs
+      enterpairs(strat->P.p,strat->sl,strat->P.ecart,0,strat, strat->tl);
+      // put in S
+      strat->enterS(strat->P,
+                    posInS(strat,strat->sl,strat->P.p, strat->P.ecart),
+                    strat, strat->tl);
+
+      // apply hilbert criterion
+      if (hilb!=NULL) khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
+
+      // clear strat->P
+      if (strat->P.lcm!=NULL) pLmFree(strat->P.lcm);
+      strat->P.lcm=NULL;
+#ifdef KDEBUG
+      // make sure kTest_TS does not complain about strat->P
+      memset(&strat->P,0,sizeof(strat->P));
+#endif
+      if (strat->sl>srmax) srmax = strat->sl; /*stat.*/
+      if (strat->Ll>lrmax) lrmax = strat->Ll;
+    }
+    if (strat->kHEdgeFound)
+    {
+      if ((BTEST1(27))
+      || ((TEST_OPT_MULTBOUND) && (scMult0Int((strat->Shdl)) < mu)))
+      {
+        // obachman: is this still used ???
+        /*
+        * stops computation if strat->kHEdgeFound and
+        * - 27 (finiteDeterminacyTest)
+        * or
+        * - 23
+        *   (multBound)
+        *   && multiplicity of the ideal is smaller then a predefined number mu
+        */
+        while (strat->Ll >= 0) deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+      }
+    }
+    kTest_TS(strat);
+  }
+  /*- complete reduction of the standard basis------------------------ -*/
+  if (TEST_OPT_REDSB) completeReduce(strat);
+  /*- release temp data------------------------------- -*/
+  exitBuchMora(strat);
+  /*- polynomials used for HECKE: HC, noether -*/
+  if (BTEST1(27))
+  {
+    if (strat->kHEdge!=NULL)
+      Kstd1_mu=pFDeg(strat->kHEdge);
+    else
+      Kstd1_mu=-1;
+  }
+  pDelete(&strat->kHEdge);
+  strat->update = TRUE; //???
+  strat->lastAxis = 0; //???
+  pDelete(&strat->kNoether);
+  omFreeSize((ADDRESS)strat->NotUsedAxis,(pVariables+1)*sizeof(BOOLEAN));
+  if (TEST_OPT_PROT) messageStat(srmax,lrmax,hilbcount,strat);
+  if (TEST_OPT_WEIGHTM)
+  {
+    pRestoreDegProcs(pFDegOld, pLDegOld);
+    if (ecartWeights)
+    {
+      omFreeSize((ADDRESS)ecartWeights,(pVariables+1)*sizeof(short));
+      ecartWeights=NULL;
+    }
+  }
+  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
+  idTest(strat->Shdl);
+  return (strat->Shdl);
+}
+
+poly kNF1 (ideal F,ideal Q,poly q, kStrategy strat, int lazyReduce)
+{
+  poly   p;
+  int   i;
+  int   j;
+  int   o;
+  LObject   h;
+  BITSET save_test=test;
+
+  if ((idIs0(F))&&(Q==NULL))
+    return pCopy(q); /*F=0*/
+  strat->ak = si_max(idRankFreeModule(F),pMaxComp(q));
+  /*- creating temp data structures------------------- -*/
+  strat->kHEdgeFound = ppNoether != NULL;
+  strat->kNoether    = pCopy(ppNoether);
+  test|=Sy_bit(OPT_REDTAIL);
+  test&=~Sy_bit(OPT_INTSTRATEGY);
+  if (TEST_OPT_STAIRCASEBOUND
+  && (! TEST_V_DEG_STOP)
+  && (0<Kstd1_deg)
+  && ((!strat->kHEdgeFound)
+    ||(TEST_OPT_DEGBOUND && (pWTotaldegree(strat->kNoether)<Kstd1_deg))))
+  {
+    pDelete(&strat->kNoether);
+    strat->kNoether=pOne();
+    pSetExp(strat->kNoether,1, Kstd1_deg+1);
+    pSetm(strat->kNoether);
+    strat->kHEdgeFound=TRUE;
+  }
+  initBuchMoraCrit(strat);
+  initBuchMoraPos(strat);
+  initMora(F,strat);
+  strat->enterS = enterSMoraNF;
+  /*- set T -*/
+  strat->tl = -1;
+  strat->tmax = setmaxT;
+  strat->T = initT();
+  strat->R = initR();
+  strat->sevT = initsevT();
+  /*- set S -*/
+  strat->sl = -1;
+  /*- init local data struct.-------------------------- -*/
+  /*Shdl=*/initS(F,Q,strat);
+  if ((strat->ak!=0)
+  && (strat->kHEdgeFound))
+  {
+    if (strat->ak!=1)
+    {
+      pSetComp(strat->kNoether,1);
+      pSetmComp(strat->kNoether);
+      poly p=pHead(strat->kNoether);
+      pSetComp(p,strat->ak);
+      pSetmComp(p);
+      p=pAdd(strat->kNoether,p);
+      strat->kNoether=pNext(p);
+      p_LmFree(p,currRing);
+    }
+  }
+  if ((lazyReduce & 1)==0)
+  {
+    for (i=strat->sl; i>=0; i--)
+      pNorm(strat->S[i]);
+  }
+  /*- puts the elements of S also to T -*/
+  for (i=0; i<=strat->sl; i++)
+  {
+    h.p = strat->S[i];
+    h.ecart = strat->ecartS[i];
+    if (strat->sevS[i] == 0) strat->sevS[i] = pGetShortExpVector(h.p);
+    else assume(strat->sevS[i] == pGetShortExpVector(h.p));
+    h.length = pLength(h.p);
+    h.sev = strat->sevS[i];
+    h.SetpFDeg();
+    enterT(h,strat);
+  }
+  /*- compute------------------------------------------- -*/
+  p = pCopy(q);
+  deleteHC(&p,&o,&j,strat);
+  if (TEST_OPT_PROT) { PrintS("r"); mflush(); }
+  if (p!=NULL) p = redMoraNF(p,strat, lazyReduce & 2);
+  if ((p!=NULL)&&((lazyReduce & 1)==0))
+  {
+    if (TEST_OPT_PROT) { PrintS("t"); mflush(); }
+    p = redtail(p,strat->sl,strat);
+  }
+  /*- release temp data------------------------------- -*/
+  cleanT(strat);
+  omFreeSize((ADDRESS)strat->T,strat->tmax*sizeof(TObject));
+  omFreeSize((ADDRESS)strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
+  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
+  omFreeSize((ADDRESS)strat->NotUsedAxis,(pVariables+1)*sizeof(BOOLEAN));
+  omfree(strat->sevT);
+  omfree(strat->S_2_R);
+  omfree(strat->R);
+
+  if ((Q!=NULL)&&(strat->fromQ!=NULL))
+  {
+    i=((IDELEMS(Q)+IDELEMS(F)+15)/16)*16;
+    omFreeSize((ADDRESS)strat->fromQ,i*sizeof(int));
+    strat->fromQ=NULL;
+  }
+  pDelete(&strat->kHEdge);
+  pDelete(&strat->kNoether);
+  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
+  {
+    pRestoreDegProcs(pFDegOld, pLDegOld);
+    if (ecartWeights)
+    {
+      omFreeSize((ADDRESS *)&ecartWeights,(pVariables+1)*sizeof(short));
+      ecartWeights=NULL;
+    }
+  }
+  idDelete(&strat->Shdl);
+  test=save_test;
+  if (TEST_OPT_PROT) PrintLn();
+  return p;
+}
+
+ideal kNF1 (ideal F,ideal Q,ideal q, kStrategy strat, int lazyReduce)
+{
+  poly   p;
+  int   i;
+  int   j;
+  int   o;
+  LObject   h;
+  ideal res;
+  BITSET save_test=test;
+
+  if (idIs0(q)) return idInit(IDELEMS(q),q->rank);
+  if ((idIs0(F))&&(Q==NULL))
+    return idCopy(q); /*F=0*/
+  strat->ak = si_max(idRankFreeModule(F),idRankFreeModule(q));
+  /*- creating temp data structures------------------- -*/
+  strat->kHEdgeFound = ppNoether != NULL;
+  strat->kNoether=pCopy(ppNoether);
+  test|=Sy_bit(OPT_REDTAIL);
+  if (TEST_OPT_STAIRCASEBOUND
+  && (0<Kstd1_deg)
+  && ((!strat->kHEdgeFound)
+    ||(TEST_OPT_DEGBOUND && (pWTotaldegree(strat->kNoether)<Kstd1_deg))))
+  {
+    pDelete(&strat->kNoether);
+    strat->kNoether=pOne();
+    pSetExp(strat->kNoether,1, Kstd1_deg+1);
+    pSetm(strat->kNoether);
+    strat->kHEdgeFound=TRUE;
+  }
+  initBuchMoraCrit(strat);
+  initBuchMoraPos(strat);
+  initMora(F,strat);
+  strat->enterS = enterSMoraNF;
+  /*- set T -*/
+  strat->tl = -1;
+  strat->tmax = setmaxT;
+  strat->T = initT();
+  strat->R = initR();
+  strat->sevT = initsevT();
+  /*- set S -*/
+  strat->sl = -1;
+  /*- init local data struct.-------------------------- -*/
+  /*Shdl=*/initS(F,Q,strat);
+  if ((strat->ak!=0)
+  && (strat->kHEdgeFound))
+  {
+    if (strat->ak!=1)
+    {
+      pSetComp(strat->kNoether,1);
+      pSetmComp(strat->kNoether);
+      poly p=pHead(strat->kNoether);
+      pSetComp(p,strat->ak);
+      pSetmComp(p);
+      p=pAdd(strat->kNoether,p);
+      strat->kNoether=pNext(p);
+      p_LmFree(p,currRing);
+    }
+  }
+  if (TEST_OPT_INTSTRATEGY && ((lazyReduce & 1)==0))
+  {
+    for (i=strat->sl; i>=0; i--)
+      pNorm(strat->S[i]);
+  }
+  /*- compute------------------------------------------- -*/
+  res=idInit(IDELEMS(q),q->rank);
+  for (i=0; i<IDELEMS(q); i++)
+  {
+    if (q->m[i]!=NULL)
+    {
+      p = pCopy(q->m[i]);
+      deleteHC(&p,&o,&j,strat);
+      if (p!=NULL)
+      {
+        /*- puts the elements of S also to T -*/
+        for (j=0; j<=strat->sl; j++)
+        {
+          h.p = strat->S[j];
+          h.ecart = strat->ecartS[j];
+          h.pLength = h.length = pLength(h.p);
+          if (strat->sevS[j] == 0) strat->sevS[j] = pGetShortExpVector(h.p);
+          else assume(strat->sevS[j] == pGetShortExpVector(h.p));
+          h.sev = strat->sevS[j];
+          h.SetpFDeg();
+          enterT(h,strat);
+        }
+        if (TEST_OPT_PROT) { PrintS("r"); mflush(); }
+        p = redMoraNF(p,strat, lazyReduce & 2);
+        if ((p!=NULL)&&((lazyReduce & 1)==0))
+        {
+          if (TEST_OPT_PROT) { PrintS("t"); mflush(); }
+          p = redtail(p,strat->sl,strat);
+        }
+        cleanT(strat);
+      }
+      res->m[i]=p;
+    }
+    //else
+    //  res->m[i]=NULL;
+  }
+  /*- release temp data------------------------------- -*/
+  omFreeSize((ADDRESS)strat->T,strat->tmax*sizeof(TObject));
+  omFreeSize((ADDRESS)strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
+  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
+  omFreeSize((ADDRESS)strat->NotUsedAxis,(pVariables+1)*sizeof(BOOLEAN));
+  omfree(strat->sevT);
+  omfree(strat->S_2_R);
+  omfree(strat->R);
+  if ((Q!=NULL)&&(strat->fromQ!=NULL))
+  {
+    i=((IDELEMS(Q)+IDELEMS(F)+15)/16)*16;
+    omFreeSize((ADDRESS)strat->fromQ,i*sizeof(int));
+    strat->fromQ=NULL;
+  }
+  pDelete(&strat->kHEdge);
+  pDelete(&strat->kNoether);
+  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
+  {
+    pFDeg=pFDegOld;
+    pLDeg=pLDegOld;
+    if (ecartWeights)
+    {
+      omFreeSize((ADDRESS *)&ecartWeights,(pVariables+1)*sizeof(short));
+      ecartWeights=NULL;
+    }
+  }
+  idDelete(&strat->Shdl);
+  test=save_test;
+  if (TEST_OPT_PROT) PrintLn();
+  return res;
+}
+
+pFDegProc pFDegOld;
+pLDegProc pLDegOld;
+intvec * kModW, * kHomW;
+
+long kModDeg(poly p, ring r)
+{
+  long o=pWDegree(p, r);
+  long i=p_GetComp(p, r);
+  if (i==0) return o;
+  assume((i>0) && (i<=kModW->length()));
+  return o+(*kModW)[i-1];
+}
+long kHomModDeg(poly p, ring r)
+{
+  int i;
+  long j=0;
+
+  for (i=r->N;i>0;i--)
+    j+=p_GetExp(p,i,r)*(*kHomW)[i-1];
+  if (kModW == NULL) return j;
+  i = p_GetComp(p,r);
+  if (i==0) return j;
+  return j+(*kModW)[i-1];
+}
+
+ideal kStd(ideal F, ideal Q, tHomog h,intvec ** w, intvec *hilb,int syzComp,
+          int newIdeal, intvec *vw)
+{
+  ideal r;
+  BOOLEAN b=pLexOrder,toReset=FALSE;
+  BOOLEAN delete_w=(w==NULL);
+  kStrategy strat=new skStrategy;
+
+  if(!TEST_OPT_RETURN_SB)
+    strat->syzComp = syzComp;
+  if (TEST_OPT_SB_1)
+    strat->newIdeal = newIdeal;
+  if (rField_has_simple_inverse())
+    strat->LazyPass=20;
+  else
+    strat->LazyPass=2;
+  strat->LazyDegree = 1;
+  strat->ak = idRankFreeModule(F);
+  strat->kModW=kModW=NULL;
+  strat->kHomW=kHomW=NULL;
+  if (vw != NULL)
+  {
+    pLexOrder=FALSE;
+    strat->kHomW=kHomW=vw;
+    pFDegOld = pFDeg;
+    pLDegOld = pLDeg;
+    pSetDegProcs(kHomModDeg);
+    toReset = TRUE;
+  }
+  if (h==testHomog)
+  {
+    if (strat->ak == 0)
+    {
+      h = (tHomog)idHomIdeal(F,Q);
+      w=NULL;
+    }
+    else if (!TEST_OPT_DEGBOUND)
+    {
+      h = (tHomog)idHomModule(F,Q,w);
+    }
+  }
+  pLexOrder=b;
+  if (h==isHomog)
+  {
+    if (strat->ak > 0 && (w!=NULL) && (*w!=NULL))
+    {
+      strat->kModW = kModW = *w;
+      if (vw == NULL)
+      {
+        pFDegOld = pFDeg;
+        pLDegOld = pLDeg;
+        pSetDegProcs(kModDeg);
+        toReset = TRUE;
+      }
+    }
+    pLexOrder = TRUE;
+    if (hilb==NULL) strat->LazyPass*=2;
+  }
+  strat->homog=h;
+#ifdef KDEBUG
+  idTest(F);
+#endif
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(currRing))
+  {
+    r=gr_bba(F,Q,strat);
+  }
+  else
+#endif
+  if (pOrdSgn==-1)
+  {
+    if (w!=NULL)
+      r=mora(F,Q,*w,hilb,strat);
+    else
+      r=mora(F,Q,NULL,hilb,strat);
+  }
+  else
+  {
+    if (w!=NULL)
+      r=bba(F,Q,*w,hilb,strat);
+    else
+      r=bba(F,Q,NULL,hilb,strat);
+  }
+#ifdef KDEBUG
+  idTest(r);
+#endif
+  if (toReset)
+  {
+    kModW = NULL;
+    pRestoreDegProcs(pFDegOld, pLDegOld);
+  }
+  pLexOrder = b;
+//Print("%d reductions canceled \n",strat->cel);
+  HCord=strat->HCord;
+  delete(strat);
+  if ((delete_w)&&(w!=NULL)&&(*w!=NULL)) delete *w;
+  return r;
+}
+
+//##############################################################
+//##############################################################
+//##############################################################
+//##############################################################
+//##############################################################
+
+ideal kMin_std(ideal F, ideal Q, tHomog h,intvec ** w, ideal &M, intvec *hilb,
+              int syzComp, int reduced)
+{
+  ideal r=NULL;
+  int Kstd1_OldDeg = Kstd1_deg,i;
+  intvec* temp_w=NULL;
+  BOOLEAN b=pLexOrder,toReset=FALSE;
+  BOOLEAN delete_w=(w==NULL);
+  BOOLEAN oldDegBound=TEST_OPT_DEGBOUND;
+  kStrategy strat=new skStrategy;
+
+  if(!TEST_OPT_RETURN_SB)
+     strat->syzComp = syzComp;
+  if (rField_has_simple_inverse())
+    strat->LazyPass=20;
+  else
+    strat->LazyPass=2;
+  strat->LazyDegree = 1;
+  strat->minim=(reduced % 2)+1;
+  strat->ak = idRankFreeModule(F);
+  if (delete_w)
+  {
+    temp_w=new intvec((strat->ak)+1);
+    w = &temp_w;
+  }
+  if ((h==testHomog)
+  )
+  {
+    if (strat->ak == 0)
+    {
+      h = (tHomog)idHomIdeal(F,Q);
+      w=NULL;
+    }
+    else
+    {
+      h = (tHomog)idHomModule(F,Q,w);
+    }
+  }
+  if (h==isHomog)
+  {
+    if (strat->ak > 0 && (w!=NULL) && (*w!=NULL))
+    {
+      kModW = *w;
+      strat->kModW = *w;
+      assume(pFDeg != NULL && pLDeg != NULL);
+      pFDegOld = pFDeg;
+      pLDegOld = pLDeg;
+      pSetDegProcs(kModDeg);
+
+      toReset = TRUE;
+      if (reduced>1)
+      {
+        Kstd1_OldDeg=Kstd1_deg;
+        Kstd1_deg = -1;
+        for (i=IDELEMS(F)-1;i>=0;i--)
+        {
+          if ((F->m[i]!=NULL) && (pFDeg(F->m[i])>=Kstd1_deg))
+            Kstd1_deg = pFDeg(F->m[i])+1;
+        }
+      }
+    }
+    pLexOrder = TRUE;
+    strat->LazyPass*=2;
+  }
+  strat->homog=h;
+  if (pOrdSgn==-1)
+  {
+    if (w!=NULL)
+      r=mora(F,Q,*w,hilb,strat);
+    else
+      r=mora(F,Q,NULL,hilb,strat);
+  }
+  else
+  {
+    if (w!=NULL)
+      r=bba(F,Q,*w,hilb,strat);
+    else
+      r=bba(F,Q,NULL,hilb,strat);
+  }
+#ifdef KDEBUG
+  {
+    int i;
+    for (i=IDELEMS(r)-1; i>=0; i--) pTest(r->m[i]);
+  }
+#endif
+  idSkipZeroes(r);
+  if (toReset)
+  {
+    pRestoreDegProcs(pFDegOld, pLDegOld);
+    kModW = NULL;
+  }
+  pLexOrder = b;
+  HCord=strat->HCord;
+  if ((delete_w)&&(temp_w!=NULL)) delete temp_w;
+  if (strat->M==NULL)
+  {
+    M=idInit(1,F->rank);
+    Warn("no minimal generating set computed");
+  }
+  else
+  {
+    idSkipZeroes(strat->M);
+    M=strat->M;
+  }
+  delete(strat);
+  if (reduced>2)
+  {
+    Kstd1_deg=Kstd1_OldDeg;
+    if (!oldDegBound)
+      test &= ~Sy_bit(OPT_DEGBOUND);
+  }
+  return r;
+}
+
+poly kNF(ideal F, ideal Q, poly p,int syzComp, int lazyReduce)
+{
+  if (p==NULL)
+     return NULL;
+  kStrategy strat=new skStrategy;
+  strat->syzComp = syzComp;
+  if (pOrdSgn==-1)
+    p=kNF1(F,Q,p,strat,lazyReduce);
+  else
+    p=kNF2(F,Q,p,strat,lazyReduce);
+  delete(strat);
+  return p;
+}
+
+ideal kNF(ideal F, ideal Q, ideal p,int syzComp,int lazyReduce)
+{
+  ideal res;
+  if (TEST_OPT_PROT)
+  {
+    Print("(S:%d)",IDELEMS(p));mflush();
+  }
+  kStrategy strat=new skStrategy;
+  strat->syzComp = syzComp;
+  if (pOrdSgn==-1)
+    res=kNF1(F,Q,p,strat,lazyReduce);
+  else
+    res=kNF2(F,Q,p,strat,lazyReduce);
+  delete(strat);
+  return res;
+}
+
+/*2
+*interreduces F
+*/
+#if 0
+// new version
+ideal kInterRed(ideal F, ideal Q)
+{
+  ideal r;
+  BOOLEAN b=pLexOrder,toReset=FALSE;
+  kStrategy strat=new skStrategy;
+  strat->interred_flag=TRUE;
+  tHomog h;
+  intvec *w=NULL;
+
+  if (rField_has_simple_inverse())
+    strat->LazyPass=20;
+  else
+    strat->LazyPass=2;
+  strat->LazyDegree = 1;
+  strat->ak = idRankFreeModule(F);
+  if (strat->ak == 0)
+  {
+    h = (tHomog)idHomIdeal(F,Q);
+  }
+  else
+  {
+    h = (tHomog)idHomModule(F,Q,&w);
+  }
+  pLexOrder=b;
+  if (h==isHomog)
+  {
+    if (strat->ak > 0 && (w!=NULL))
+    {
+      strat->kModW = kModW = w;
+      pFDegOld = pFDeg;
+      pLDegOld = pLDeg;
+      pSetDegProcs(kModDeg);
+      toReset = TRUE;
+    }
+    pLexOrder = TRUE;
+    strat->LazyPass*=2;
+  }
+  strat->homog=h;
+#ifdef KDEBUG
+  idTest(F);
+#endif
+  if (pOrdSgn==-1)
+  {
+    if (w!=NULL)
+      r=mora(F,Q,w,NULL,strat);
+    else
+      r=mora(F,Q,NULL,NULL,strat);
+  }
+  else
+  {
+    if (w!=NULL)
+      r=bba(F,Q,w,NULL,strat);
+    else
+      r=bba(F,Q,NULL,NULL,strat);
+  }
+#ifdef KDEBUG
+  idTest(r);
+#endif
+  if (toReset)
+  {
+    kModW = NULL;
+    pRestoreDegProcs(pFDegOld, pLDegOld);
+  }
+  pLexOrder = b;
+//Print("%d reductions canceled \n",strat->cel);
+  HCord=strat->HCord;
+  delete(strat);
+  if (w!=NULL) delete w;
+  return r;
+}
+#else
+// old version
+ideal kInterRed (ideal F, ideal Q)
+{
+  int j;
+  kStrategy strat = new skStrategy;
+
+//  if (TEST_OPT_PROT)
+//  {
+//    writeTime("start InterRed:");
+//    mflush();
+//  }
+  //strat->syzComp     = 0;
+  strat->kHEdgeFound = ppNoether != NULL;
+  strat->kNoether=pCopy(ppNoether);
+  strat->ak = idRankFreeModule(F);
+  initBuchMoraCrit(strat);
+  strat->NotUsedAxis = (BOOLEAN *)omAlloc((pVariables+1)*sizeof(BOOLEAN));
+  for (j=pVariables; j>0; j--) strat->NotUsedAxis[j] = TRUE;
+  strat->enterS      = enterSBba;
+  strat->posInT      = posInT17;
+  strat->initEcart   = initEcartNormal;
+  strat->sl   = -1;
+  strat->tl          = -1;
+  strat->tmax        = setmaxT;
+  strat->T           = initT();
+  strat->R           = initR();
+  strat->sevT        = initsevT();
+  if (pOrdSgn == -1)   strat->honey = TRUE;
+  initS(F,Q,strat);
+  if (TEST_OPT_REDSB)
+    strat->noTailReduction=FALSE;
+  updateS(TRUE,strat);
+  if (TEST_OPT_REDSB && TEST_OPT_INTSTRATEGY)
+    completeReduce(strat);
+  pDelete(&strat->kHEdge);
+  omFreeSize((ADDRESS)strat->T,strat->tmax*sizeof(TObject));
+  omFreeSize((ADDRESS)strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
+  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
+  omFreeSize((ADDRESS)strat->NotUsedAxis,(pVariables+1)*sizeof(BOOLEAN));
+  omfree(strat->sevT);
+  omfree(strat->S_2_R);
+  omfree(strat->R);
+
+  if (strat->fromQ)
+  {
+    for (j=IDELEMS(strat->Shdl)-1;j>=0;j--)
+    {
+      if(strat->fromQ[j]) pDelete(&strat->Shdl->m[j]);
+    }
+    omFreeSize((ADDRESS)strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
+    strat->fromQ=NULL;
+  }
+//  if (TEST_OPT_PROT)
+//  {
+//    writeTime("end Interred:");
+//    mflush();
+//  }
+  ideal shdl=strat->Shdl;
+  idSkipZeroes(shdl);
+  delete(strat);
+  return shdl;
+}
+#endif
+
+// returns TRUE if mora should use buckets, false otherwise
+static BOOLEAN kMoraUseBucket(kStrategy strat)
+{
+#ifdef MORA_USE_BUCKETS
+  if (TEST_OPT_NOT_BUCKETS)
+    return FALSE;
+  if (strat->red == redFirst)
+  {
+#ifdef NO_LDEG
+    if (!strat->syzComp)
+      return TRUE;
+#else
+    if ((strat->homog || strat->honey) && !strat->syzComp)
+      return TRUE;
+#endif
+  }
+  else
+  {
+    assume(strat->red == redEcart);
+    if (strat->honey && !strat->syzComp)
+      return TRUE;
+  }
+#endif
+  return FALSE;
+}
Index: kernel/kstd1.h
===================================================================
--- kernel/kstd1.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/kstd1.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,83 @@
+#ifndef KSTD1_H
+#define KSTD1_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: kstd1.h,v 1.1.1.1 2003-10-06 12:15:53 Singular Exp $ */
+/*
+* ABSTRACT
+*/
+#include "structs.h"
+
+/*2
+*input: F: a set (array) of polys with <= Fmax entries (0..Fmax-1)
+*       *S: a set (array) of polys with *Smax initialized entries (0..*Smax-1)
+*output:*S: the standard base: a set (array) with <= *Smax+1 entries (0..*Smax)
+*/
+ideal mora (ideal F, ideal Q,intvec *w,intvec *hilb,kStrategy strat);
+
+poly kNF1(ideal F, ideal Q, poly q, kStrategy strat, int lazyReduce);
+ideal kNF1 (ideal F,ideal Q,ideal q, kStrategy strat, int lazyReduce);
+
+poly kNF (ideal F, ideal Q, poly p,int syzComp=0, int lazyReduce=0);
+ideal kNF(ideal F, ideal Q, ideal p,int syzComp=0, int lazyReduce=0);
+
+ideal kStd(ideal F, ideal Q, tHomog h, intvec ** mw,intvec *hilb=NULL,
+          int syzComp=0,int newIdeal=0, intvec *vw=NULL);
+
+/* the following global data are defined in kutil.cc */
+//extern int syzComp;
+  /*stop building pairs after that component --> ideals.cc, syz.cc */
+extern int LazyPass,LazyDegree,mu,Kstd1_deg;
+#define Kstd1_mu mu
+  /*parameters for Lazy or global stops --> ipshell.cc, grammar.y*/
+extern BITSET kOptions;
+  /*the known test options (a constant)*/
+extern BITSET validOpts;
+
+void initMora(ideal F,kStrategy strat);
+
+ideal kInterRed (ideal F, ideal Q=NULL);
+long   kModDeg(poly p, ring r = currRing);
+long  kHomModDeg(poly p, ring r = currRing);
+
+ideal stdred(ideal F, ideal Q, tHomog h,intvec ** w);
+
+ideal kMin_std(ideal F, ideal Q, tHomog h,intvec ** w, ideal &M,
+              intvec *hilb=NULL, int syzComp=0,int reduced=0);
+
+
+extern pFDegProc pFDegOld;
+extern pLDegProc pLDegOld;
+extern intvec * kModW;
+
+/* options:
+0 prot
+1 redSB
+2 Gebauer/Moeller: obachman 10/00: replaced by notBucket
+3 notSugar
+4 interrupt
+5 sugarCrit
+6 teach
+7 cancel unit: obachman 11/00 tossed
+8 morepairs: obachman 11/00: tossed
+9 return SB (syz,quotient,intersect)
+10 fastHC
+11-19 sort in L/T
+20 redBest: obachman 11/00 tossed
+21 keep local variable with keepring of a loacal ring
+22 staircaseBound: in NF create a HC x1^degBound+1
+23 multBound
+24 degBound
+25 no redTail(p)/redTail(s)
+26 integer strategy
+27 stop at HC (finiteDeterminacyTest)
+28 infRedTail: ignore ecart in local redTail-calls
+29 kStd + 1 new element
+30 noRedSyz
+31 weight
+verbose:31 stop at certain weights
+*/
+
+#endif
+
Index: kernel/kstd2.cc
===================================================================
--- kernel/kstd2.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/kstd2.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,757 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: kstd2.cc,v 1.1.1.1 2003-10-06 12:15:54 Singular Exp $ */
+/*
+*  ABSTRACT -  Kernel: alg. of Buchberger
+*/
+
+// #define PDEBUG 2
+// define to enable tailRings
+#define HAVE_TAIL_RING
+// define if no buckets should be used
+// #define NO_BUCKETS
+
+#include "mod2.h"
+#include "kutil.h"
+#include "structs.h"
+#include "omalloc.h"
+#include "polys.h"
+#include "ideals.h"
+#include "febase.h"
+#include "kstd1.h"
+#include "khstd.h"
+#include "kbuckets.h"
+//#include "cntrlc.h"
+#include "weight.h"
+#include "intvec.h"
+#ifdef HAVE_PLURAL
+#include "gring.h"
+#endif
+// #include "timer.h"
+
+// return -1 if no divisor is found
+//        number of first divisor, otherwise
+int kFindDivisibleByInT(const TSet &T, const unsigned long* sevT,
+                        const int tl, const LObject* L, const int start)
+{
+  unsigned long not_sev = ~L->sev;
+  int j = start;
+  poly p;
+  ring r;
+  L->GetLm(p, r);
+
+  pAssume(~not_sev == p_GetShortExpVector(p, r));
+
+  if (r == currRing)
+  {
+    loop
+    {
+      if (j > tl) return -1;
+#if defined(PDEBUG) || defined(PDIV_DEBUG)
+      if (p_LmShortDivisibleBy(T[j].p, sevT[j],
+                               p, not_sev, r))
+        return j;
+#else
+      if (!(sevT[j] & not_sev) &&
+          p_LmDivisibleBy(T[j].p, p, r))
+        return j;
+#endif
+      j++;
+    }
+  }
+  else
+  {
+    loop
+    {
+      if (j > tl) return -1;
+#if defined(PDEBUG) || defined(PDIV_DEBUG)
+      if (p_LmShortDivisibleBy(T[j].t_p, sevT[j],
+                               p, not_sev, r))
+        return j;
+#else
+      if (!(sevT[j] & not_sev) &&
+          p_LmDivisibleBy(T[j].t_p, p, r))
+        return j;
+#endif
+      j++;
+    }
+  }
+}
+
+// same as above, only with set S
+int kFindDivisibleByInS(const polyset &S, const unsigned long* sev, const int sl, LObject* L)
+{
+  unsigned long not_sev = ~L->sev;
+  poly p = L->GetLmCurrRing();
+  int j = 0;
+
+  pAssume(~not_sev == p_GetShortExpVector(p, currRing));
+  loop
+  {
+    if (j > sl) return -1;
+#if defined(PDEBUG) || defined(PDIV_DEBUG)
+    if (p_LmShortDivisibleBy(S[j], sev[j],
+                             p, not_sev, currRing))
+        return j;
+#else
+    if ( !(sev[j] & not_sev) &&
+         p_LmDivisibleBy(S[j], p, currRing))
+      return j;
+#endif
+    j++;
+  }
+}
+
+/*2
+*  reduction procedure for the homogeneous case
+*  and the case of a degree-ordering
+*/
+int redHomog (LObject* h,kStrategy strat)
+{
+//  if (strat->tl<0) return 1;
+#ifdef KDEBUG
+  if (TEST_OPT_DEBUG)
+  {
+    PrintS("red:");
+    h->wrp();
+    PrintS(" ");
+  }
+#endif
+  int j;
+  loop
+  {
+    // find a poly with which we can reduce
+    h->SetShortExpVector();
+    j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, h);
+    if (j < 0)
+    {
+      h->SetpFDeg();
+      return 1;
+    }
+
+    // now we found one which is divisible -- reduce it
+    ksReducePoly(h, &(strat->T[j]), NULL, NULL, strat);
+
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      Print("\nto ", h->t_p);
+      h->wrp();
+      PrintLn();
+    }
+#endif
+    if (h->GetLmTailRing() == NULL)
+    {
+      if (h->lcm!=NULL) pLmFree(h->lcm);
+#ifdef KDEBUG
+      h->lcm=NULL;
+#endif
+      return 0;
+    }
+  }
+}
+
+
+/*2
+*  reduction procedure for the inhomogeneous case
+*  and not a degree-ordering
+*/
+int redLazy (LObject* h,kStrategy strat)
+{
+  if (strat->tl<0) return 1;
+  int at,d,i;
+  int j = 0;
+  int pass = 0;
+  assume(h->pFDeg() == h->FDeg);
+  long reddeg = h->GetpFDeg();
+
+  h->SetShortExpVector();
+  loop
+  {
+    j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, h);
+    if (j < 0) return 1;
+
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("red:");
+      h->wrp();
+      PrintS(" with ");
+      strat->T[j].wrp();
+    }
+#endif
+
+    ksReducePoly(h, &(strat->T[j]), NULL, NULL, strat);
+
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("\nto ");
+      h->wrp();
+      PrintLn();
+    }
+#endif
+
+    if (h->GetLmTailRing() == NULL)
+    {
+      if (h->lcm!=NULL) pLmFree(h->lcm);
+#ifdef KDEBUG
+      h->lcm=NULL;
+#endif
+      return 0;
+    }
+    h->SetShortExpVector();
+    d = h->SetpFDeg();
+    /*- try to reduce the s-polynomial -*/
+    pass++;
+    if (!K_TEST_OPT_REDTHROUGH &&
+        (strat->Ll >= 0) && ((d > reddeg) || (pass > strat->LazyPass)))
+    {
+      h->SetLmCurrRing();
+      at = posInL11(strat->L,strat->Ll,h,strat);
+      if (at <= strat->Ll)
+      {
+        if (kFindDivisibleByInS(strat->S, strat->sevS, strat->sl, h) < 0)
+          return 1;
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG) Print(" ->L[%d]\n",at);
+#endif
+        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+        h->Clear();
+        return -1;
+      }
+    }
+    else if ((TEST_OPT_PROT) && (strat->Ll < 0) && (d != reddeg))
+    {
+      Print(".%d",d);mflush();
+      reddeg = d;
+    }
+  }
+}
+
+/*2
+*  reduction procedure for the sugar-strategy (honey)
+* reduces h with elements from T choosing first possible
+* element in T with respect to the given ecart
+*/
+int redHoney (LObject* h, kStrategy strat)
+{
+  if (strat->tl<0) return 1;
+  assume(h->FDeg == h->pFDeg());
+
+  poly h_p;
+  int i,j,at,pass,ei, ii, h_d;
+  unsigned long not_sev;
+  long reddeg,d;
+
+  pass = j = 0;
+  d = reddeg = h->GetpFDeg() + h->ecart;
+  h->SetShortExpVector();
+  h_p = h->GetLmTailRing();
+  not_sev = ~ h->sev;
+  loop
+  {
+    j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, h);
+    if (j < 0) return 1;
+
+    ei = strat->T[j].ecart;
+    ii = j;
+    /*
+     * the polynomial to reduce with (up to the moment) is;
+     * pi with ecart ei
+     */
+    i = j;
+    loop
+    {
+      /*- takes the first possible with respect to ecart -*/
+      i++;
+      if (i > strat->tl)
+        break;
+      if (ei <= h->ecart)
+        break;
+      if ((strat->T[i].ecart < ei) &&
+          p_LmShortDivisibleBy(strat->T[i].GetLmTailRing(), strat->sevT[i],
+                               h_p, not_sev, strat->tailRing))
+      {
+        /*
+         * the polynomial to reduce with is now;
+         */
+        ei = strat->T[i].ecart;
+        ii = i;
+      }
+    }
+
+    /*
+     * end of search: have to reduce with pi
+     */
+    if (!K_TEST_OPT_REDTHROUGH && (pass!=0) && (ei > h->ecart))
+    {
+      h->SetLmCurrRing();
+      /*
+       * It is not possible to reduce h with smaller ecart;
+       * if possible h goes to the lazy-set L,i.e
+       * if its position in L would be not the last one
+       */
+      if (strat->Ll >= 0) /* L is not empty */
+      {
+        at = strat->posInL(strat->L,strat->Ll,h,strat);
+        if(at <= strat->Ll)
+          /*- h will not become the next element to reduce -*/
+        {
+          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+#ifdef KDEBUG
+          if (TEST_OPT_DEBUG) Print(" ecart too big: -> L%d\n",at);
+#endif
+          h->Clear();
+          return -1;
+        }
+      }
+    }
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("red:");
+      h->wrp();
+      PrintS(" with ");
+      strat->T[ii].wrp();
+    }
+#endif
+    assume(strat->fromT == FALSE);
+
+    ksReducePoly(h, &(strat->T[ii]), NULL, NULL, strat);
+
+#ifdef KDEBUG
+    if (TEST_OPT_DEBUG)
+    {
+      PrintS("\nto ");
+      h->wrp();
+      PrintLn();
+    }
+#endif
+
+    h_p = h->GetLmTailRing();
+    if (h_p == NULL)
+    {
+      if (h->lcm!=NULL) pLmFree(h->lcm);
+#ifdef KDEBUG
+      h->lcm=NULL;
+#endif
+      return 0;
+    }
+    h->SetShortExpVector();
+    not_sev = ~ h->sev;
+    h_d = h->SetpFDeg();
+    /* compute the ecart */
+    if (ei <= h->ecart)
+      h->ecart = d-h_d;
+    else
+      h->ecart = d-h_d+ei-h->ecart;
+    /*
+     * try to reduce the s-polynomial h
+     *test first whether h should go to the lazyset L
+     *-if the degree jumps
+     *-if the number of pre-defined reductions jumps
+     */
+    pass++;
+    d = h_d + h->ecart;
+    if (!K_TEST_OPT_REDTHROUGH && (strat->Ll >= 0) && ((d > reddeg) || (pass > strat->LazyPass)))
+    {
+      h->SetLmCurrRing();
+      at = strat->posInL(strat->L,strat->Ll,h,strat);
+      if (at <= strat->Ll)
+      {
+        if (kFindDivisibleByInS(strat->S, strat->sevS, strat->sl, h) < 0)
+          return 1;
+        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+          Print(" degree jumped: -> L%d\n",at);
+#endif
+        h->Clear();
+        return -1;
+      }
+    }
+    else if (TEST_OPT_PROT && (strat->Ll < 0) && (d > reddeg))
+    {
+      reddeg = d;
+      Print(".%d",d); mflush();
+    }
+  }
+}
+/*2
+*  reduction procedure for the normal form
+*/
+
+poly redNF (poly h,kStrategy strat)
+{
+  if (h==NULL) return NULL;
+  int j;
+
+  if (0 > strat->sl)
+  {
+    return h;
+  }
+  LObject P(h);
+  P.SetShortExpVector();
+  P.bucket = kBucketCreate(currRing);
+  kBucketInit(P.bucket,P.p,pLength(P.p));
+  loop
+  {
+    j=kFindDivisibleByInS(strat->S,strat->sevS,strat->sl,&P);
+    if (j>=0)
+    {
+      nNormalize(pGetCoeff(P.p));
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("red:");
+        wrp(h);
+        PrintS(" with ");
+        wrp(strat->S[j]);
+      }
+#endif
+#ifdef HAVE_PLURAL
+      if (rIsPluralRing(currRing))
+      {
+	number coef;
+        nc_kBucketPolyRed(P.bucket,strat->S[j],&coef);
+	nDelete(&coef);
+      }
+      else
+#endif
+      {
+        number coef;
+        coef=kBucketPolyRed(P.bucket,strat->S[j],pLength(strat->S[j]),strat->kNoether);
+        nDelete(&coef);
+      }
+      h = kBucketGetLm(P.bucket);
+      if (h==NULL)
+      {
+        kBucketDestroy(&P.bucket);
+        return NULL;
+      }
+      P.p=h;
+      P.t_p=NULL;
+      P.SetShortExpVector();
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("\nto:");
+        wrp(h);
+        PrintLn();
+      }
+#endif
+    }
+    else
+    {
+      P.p=kBucketClear(P.bucket);
+      kBucketDestroy(&P.bucket);
+      pNormalize(P.p);
+      return P.p;
+    }
+  }
+}
+
+#ifdef KDEBUG
+static int bba_count = 0;
+#endif
+
+ideal bba (ideal F, ideal Q,intvec *w,intvec *hilb,kStrategy strat)
+{
+#ifdef KDEBUG
+  bba_count++;
+  int loop_count = 0;
+#endif
+  om_Opts.MinTrack = 5;
+  int   srmax,lrmax, red_result = 1;
+  int   olddeg,reduc;
+  int hilbeledeg=1,hilbcount=0,minimcnt=0;
+  BOOLEAN withT = FALSE;
+
+  initBuchMoraCrit(strat); /*set Gebauer, honey, sugarCrit*/
+  initBuchMoraPos(strat);
+  initHilbCrit(F,Q,&hilb,strat);
+  initBba(F,strat);
+  /*set enterS, spSpolyShort, reduce, red, initEcart, initEcartPair*/
+  /*Shdl=*/initBuchMora(F, Q,strat);
+  if (strat->minim>0) strat->M=idInit(IDELEMS(F),F->rank);
+  srmax = strat->sl;
+  reduc = olddeg = lrmax = 0;
+
+#ifndef NO_BUCKETS
+  if (!TEST_OPT_NOT_BUCKETS)
+    strat->use_buckets = 1;
+#endif
+
+  // redtailBBa against T for inhomogenous input
+  if (!K_TEST_OPT_OLDSTD)
+    withT = ! strat->homog;
+
+  // strat->posInT = posInT_pLength;
+  kTest_TS(strat);
+
+#ifdef HAVE_TAIL_RING
+  kStratInitChangeTailRing(strat);
+#endif
+
+  /* compute------------------------------------------------------- */
+  while (strat->Ll >= 0)
+  {
+    if (strat->Ll > lrmax) lrmax =strat->Ll;/*stat.*/
+#ifdef KDEBUG
+    loop_count++;
+    if (TEST_OPT_DEBUG) messageSets(strat);
+#endif
+    if (strat->Ll== 0) strat->interpt=TRUE;
+    if (TEST_OPT_DEGBOUND
+        && ((strat->honey && (strat->L[strat->Ll].ecart+pFDeg(strat->L[strat->Ll].p)>Kstd1_deg))
+            || ((!strat->honey) && (pFDeg(strat->L[strat->Ll].p)>Kstd1_deg))))
+    {
+      /*
+       *stops computation if
+       * 24 IN test and the degree +ecart of L[strat->Ll] is bigger then
+       *a predefined number Kstd1_deg
+       */
+      while (strat->Ll >= 0) deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+      break;
+    }
+    /* picks the last element from the lazyset L */
+    strat->P = strat->L[strat->Ll];
+    strat->Ll--;
+
+    if (pNext(strat->P.p) == strat->tail)
+    {
+      // deletes the short spoly
+      pLmFree(strat->P.p);
+      strat->P.p = NULL;
+      poly m1 = NULL, m2 = NULL;
+
+      // check that spoly creation is ok
+      while (strat->tailRing != currRing &&
+             !kCheckSpolyCreation(&(strat->P), strat, m1, m2))
+      {
+        assume(m1 == NULL && m2 == NULL);
+        // if not, change to a ring where exponents are at least
+        // large enough
+        kStratChangeTailRing(strat);
+      }
+      // create the real one
+      ksCreateSpoly(&(strat->P), NULL, strat->use_buckets,
+                    strat->tailRing, m1, m2, strat->R);
+    }
+    else if (strat->P.p1 == NULL)
+    {
+      if (strat->minim > 0)
+        strat->P.p2=p_Copy(strat->P.p, currRing, strat->tailRing);
+      // for input polys, prepare reduction
+      strat->P.PrepareRed(strat->use_buckets);
+    }
+
+    if (TEST_OPT_PROT)
+      message((strat->honey ? strat->P.ecart : 0) + strat->P.pFDeg(),
+              &olddeg,&reduc,strat, red_result);
+
+    /* reduction of the element choosen from L */
+    red_result = strat->red(&strat->P,strat);
+
+    // reduction to non-zero new poly
+    if (red_result == 1)
+    {
+      /* statistic */
+      if (TEST_OPT_PROT) PrintS("s");
+
+      // get the polynomial (canonicalize bucket, make sure P.p is set)
+      strat->P.GetP(strat->lmBin);
+
+      int pos=posInS(strat,strat->sl,strat->P.p,strat->P.ecart);
+
+      // reduce the tail and normalize poly
+      if (TEST_OPT_INTSTRATEGY)
+      {
+        strat->P.pCleardenom();
+        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
+        {
+          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
+          strat->P.pCleardenom();
+        }
+      }
+      else
+      {
+        strat->P.pNorm();
+        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
+          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
+      }
+
+#ifdef KDEBUG
+      if (TEST_OPT_DEBUG){PrintS("new s:");strat->P.wrp();PrintLn();}
+#endif
+
+      // min_std stuff
+      if ((strat->P.p1==NULL) && (strat->minim>0))
+      {
+        if (strat->minim==1)
+        {
+          strat->M->m[minimcnt]=p_Copy(strat->P.p,currRing,strat->tailRing);
+          p_Delete(&strat->P.p2, currRing, strat->tailRing);
+        }
+        else
+        {
+          strat->M->m[minimcnt]=strat->P.p2;
+          strat->P.p2=NULL;
+        }
+        if (strat->tailRing!=currRing && pNext(strat->M->m[minimcnt])!=NULL)
+          pNext(strat->M->m[minimcnt])
+            = strat->p_shallow_copy_delete(pNext(strat->M->m[minimcnt]),
+                                           strat->tailRing, currRing,
+                                           currRing->PolyBin);
+        minimcnt++;
+      }
+
+      // enter into S, L, and T
+      enterT(strat->P, strat);
+      enterpairs(strat->P.p,strat->sl,strat->P.ecart,pos,strat, strat->tl);
+      // posInS only depends on the leading term
+      strat->enterS(strat->P, pos, strat, strat->tl);
+      if (hilb!=NULL) khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
+//      Print("[%d]",hilbeledeg);
+      if (strat->P.lcm!=NULL) pLmFree(strat->P.lcm);
+      if (strat->sl>srmax) srmax = strat->sl;
+    }
+    else if (strat->P.p1 == NULL && strat->minim > 0)
+    {
+      p_Delete(&strat->P.p2, currRing, strat->tailRing);
+    }
+#ifdef KDEBUG
+    memset(&(strat->P), 0, sizeof(strat->P));
+#endif
+    kTest_TS(strat);
+  }
+#ifdef KDEBUG
+  if (TEST_OPT_DEBUG) messageSets(strat);
+#endif
+  /* complete reduction of the standard basis--------- */
+  if (TEST_OPT_REDSB) completeReduce(strat);
+  /* release temp data-------------------------------- */
+  exitBuchMora(strat);
+  if (TEST_OPT_WEIGHTM)
+  {
+    pRestoreDegProcs(pFDegOld, pLDegOld);
+    if (ecartWeights)
+    {
+      omFreeSize((ADDRESS)ecartWeights,(pVariables+1)*sizeof(short));
+      ecartWeights=NULL;
+    }
+  }
+  if (TEST_OPT_PROT) messageStat(srmax,lrmax,hilbcount,strat);
+  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
+  return (strat->Shdl);
+}
+
+poly kNF2 (ideal F,ideal Q,poly q,kStrategy strat, int lazyReduce)
+{
+  poly   p;
+  int   i;
+
+  if ((idIs0(F))&&(Q==NULL))
+    return pCopy(q); /*F=0*/
+  strat->ak = idRankFreeModule(F);
+  /*- creating temp data structures------------------- -*/
+  BITSET save_test=test;
+  test|=Sy_bit(OPT_REDTAIL);
+  initBuchMoraCrit(strat);
+  strat->initEcart = initEcartBBA;
+  strat->enterS = enterSBba;
+  /*- set S -*/
+  strat->sl = -1;
+  /*- init local data struct.---------------------------------------- -*/
+  /*Shdl=*/initS(F,Q,strat);
+  /*- compute------------------------------------------------------- -*/
+  //if ((TEST_OPT_INTSTRATEGY)&&(lazyReduce==0))
+  {
+    for (i=strat->sl;i>=0;i--)
+      pNorm(strat->S[i]);
+  }
+  kTest(strat);
+  if (TEST_OPT_PROT) { PrintS("r"); mflush(); }
+  p = redNF(pCopy(q),strat);
+  if ((p!=NULL)&&(lazyReduce==0))
+  {
+    if (TEST_OPT_PROT) { PrintS("t"); mflush(); }
+    p = redtailBba(p,strat->sl,strat);
+  }
+  /*- release temp data------------------------------- -*/
+  omfree(strat->sevS);
+  omfree(strat->ecartS);
+  omfree(strat->T);
+  omfree(strat->sevT);
+  omfree(strat->R);
+  omfree(strat->S_2_R);
+  omfree(strat->L);
+  omfree(strat->B);
+  omfree(strat->fromQ);
+  idDelete(&strat->Shdl);
+  test=save_test;
+  if (TEST_OPT_PROT) PrintLn();
+  return p;
+}
+
+ideal kNF2 (ideal F,ideal Q,ideal q,kStrategy strat, int lazyReduce)
+{
+  poly   p;
+  int   i;
+  ideal res;
+
+  if (idIs0(q))
+    return idInit(IDELEMS(q),q->rank);
+  if ((idIs0(F))&&(Q==NULL))
+    return idCopy(q); /*F=0*/
+  strat->ak = idRankFreeModule(F);
+  /*- creating temp data structures------------------- -*/
+  BITSET save_test=test;
+  test|=Sy_bit(OPT_REDTAIL);
+  initBuchMoraCrit(strat);
+  strat->initEcart = initEcartBBA;
+  strat->enterS = enterSBba;
+  /*- set S -*/
+  strat->sl = -1;
+  /*- init local data struct.---------------------------------------- -*/
+  /*Shdl=*/initS(F,Q,strat);
+  /*- compute------------------------------------------------------- -*/
+  res=idInit(IDELEMS(q),q->rank);
+  //if ((TEST_OPT_INTSTRATEGY)&&(lazyReduce==0))
+  {
+    for (i=strat->sl;i>=0;i--)
+      pNorm(strat->S[i]);
+  }
+  for (i=IDELEMS(q)-1; i>=0; i--)
+  {
+    if (q->m[i]!=NULL)
+    {
+      if (TEST_OPT_PROT) { PrintS("r");mflush(); }
+      p = redNF(pCopy(q->m[i]),strat);
+      if ((p!=NULL)&&(lazyReduce==0))
+      {
+        if (TEST_OPT_PROT) { PrintS("t"); mflush(); }
+        p = redtailBba(p,strat->sl,strat);
+      }
+      res->m[i]=p;
+    }
+    //else
+    //  res->m[i]=NULL;
+  }
+  /*- release temp data------------------------------- -*/
+  omfree(strat->sevS);
+  omfree(strat->ecartS);
+  omfree(strat->T);
+  omfree(strat->sevT);
+  omfree(strat->R);
+  omfree(strat->S_2_R);
+  omfree(strat->L);
+  omfree(strat->B);
+  omfree(strat->fromQ);
+  idDelete(&strat->Shdl);
+  test=save_test;
+  if (TEST_OPT_PROT) PrintLn();
+  return res;
+}
Index: kernel/kstdfac.cc
===================================================================
--- kernel/kstdfac.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/kstdfac.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,937 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: kstdfac.cc,v 1.1.1.1 2003-10-06 12:15:56 Singular Exp $ */
+/*
+*  ABSTRACT -  Kernel: factorizing alg. of Buchberger
+*/
+
+#include "mod2.h"
+#include "structs.h"
+#include "omalloc.h"
+#include "polys.h"
+#include "ideals.h"
+#include "febase.h"
+#include "kutil.h"
+#include "kstd1.h"
+#include "khstd.h"
+//#include "cntrlc.h"
+#include "weight.h"
+//#include "ipshell.h"
+#include "intvec.h"
+#ifdef HAVE_FACTORY
+#include "clapsing.h"
+#endif
+#include "ideals.h"
+#include "timer.h"
+#include "kstdfac.h"
+
+#ifdef HAVE_FACTORY
+/*3
+* copy o->T to n->T, assumes that n->S is already copied
+*/
+static void copyT (kStrategy o,kStrategy n)
+{
+  int i,j;
+  poly  p;
+  TSet t=(TSet)omAlloc0(o->tmax*sizeof(TObject));
+  TObject** r = (TObject**)omAlloc0(o->tmax*sizeof(TObject*));
+
+  for (j=0; j<=o->tl; j++)
+  {
+    t[j] = o->T[j];
+    r[t[j].i_r] = &t[j];
+    p = o->T[j].p;
+    i = -1;
+    loop
+    {
+      i++;
+      if (i>o->sl)
+      {
+        t[j].p=pCopy(p);
+        break;
+      }
+      if (p == o->S[i])
+      {
+        t[j].p=n->S[i];
+        break;
+      }
+    }
+    t[j].t_p = NULL; // ?? or t[j].p ??
+    t[j].max = NULL; // ?? or p_GetMaxExpP(t[j].t_p,o->tailRing); ??
+  }
+  n->T=t;
+  n->R=r;
+}
+
+/*3
+* copy o->L to n->L, assumes that n->T,n->tail is already copied
+*/
+static void copyL (kStrategy o,kStrategy n)
+{
+  int i,j;
+  poly  p;
+  LSet l=(LSet)omAlloc(o->Lmax*sizeof(LObject));
+
+  for (j=0; j<=o->Ll; j++)
+  {
+    l[j] = o->L[j];
+    // copy .p ----------------------------------------------
+    if (pNext(o->L[j].p)!=o->tail)
+      l[j].p=pCopy(o->L[j].p);
+    else
+    {
+      l[j].p=pHead(o->L[j].p);
+      pNext(l[j].p)=n->tail;
+    }
+    // copy .lcm ----------------------------------------------
+    if (o->L[j].lcm!=NULL)
+      l[j].lcm=pLmInit(o->L[j].lcm);
+    else
+      l[j].lcm=NULL;
+    l[j].p1=NULL;
+    l[j].p2=NULL;
+    l[j].t_p = NULL;
+
+    // copy .p1 , i_r1----------------------------------------------
+    p = o->L[j].p1;
+    i = -1;
+    loop
+    {
+      if(p==NULL) break;
+      i++;
+      if(i>o->tl)
+      {
+        Warn("poly p1 not found in T:");wrp(p);PrintLn();
+        l[j].p1=pCopy(p);
+        l[j].i_r1=-1;
+        break;
+      }
+      if (p == o->T[i].p)
+      {
+        l[j].p1=n->T[i].p;
+        l[j].i_r1=n->T[i].i_r;
+        break;
+      }
+    }
+
+    // copy .p2 , i_r2----------------------------------------------
+    p = o->L[j].p2;
+    i = -1;
+    loop
+    {
+      if(p==NULL) break;
+      i++;
+      if(i>o->tl)
+      {
+        Warn("poly p2 not found in T:");wrp(p);PrintLn();
+        l[j].p2=pCopy(p);
+        l[j].i_r2=-1;
+        break;
+      }
+      if (p == o->T[i].p)
+      {
+        l[j].p2=n->T[i].p;
+        l[j].i_r2=n->T[i].i_r;
+        break;
+      }
+    }
+
+    // copy .ecart ---------------------------------------------
+    l[j].ecart=o->L[j].ecart;
+    // copy .length --------------------------------------------
+    l[j].length=o->L[j].length;
+    // copy .pLength -------------------------------------------
+    l[j].pLength=o->L[j].pLength;
+    // copy .sev -----------------------------------------------
+    l[j].sev=o->L[j].sev;
+    l[j].i_r = o->L[j].i_r;
+    //l[j].i_r1 = o->L[j].i_r1;
+    //l[j].i_r2 = o->L[j].i_r2;
+  }
+  n->L=l;
+}
+
+kStrategy kStratCopy(kStrategy o)
+{
+  int i;
+  kTest_TS(o);
+  kStrategy s=new skStrategy;
+  s->next=NULL;
+  s->red=o->red;
+  s->initEcart=o->initEcart;
+  s->posInT=o->posInT;
+  s->posInL=o->posInL;
+  s->enterS=o->enterS;
+  s->initEcartPair=o->initEcartPair;
+  s->posInLOld=o->posInLOld;
+  s->Shdl=idCopy(o->Shdl);
+  s->S=s->Shdl->m;
+  s->tailRing = o->tailRing;
+  if (o->D!=NULL) s->D=idCopy(o->D);
+  else            s->D=NULL;
+  s->ecartS=(int *)omAlloc(IDELEMS(o->Shdl)*sizeof(int));
+  memcpy(s->ecartS,o->ecartS,IDELEMS(o->Shdl)*sizeof(int));
+  s->sevS=(unsigned long *)omAlloc(IDELEMS(o->Shdl)*sizeof(unsigned long));
+  memcpy(s->sevS,o->sevS,IDELEMS(o->Shdl)*sizeof(unsigned long));
+  s->S_2_R=(int*)omAlloc(IDELEMS(o->Shdl)*sizeof(int));
+  memcpy(s->S_2_R,o->S_2_R,IDELEMS(o->Shdl)*sizeof(int));
+  s->sevT=(unsigned long *)omAlloc(o->tmax*sizeof(unsigned long));
+  memcpy(s->sevT,o->sevT,o->tmax*sizeof(unsigned long));
+  if(o->fromQ!=NULL)
+  {
+    s->fromQ=(int *)omAlloc(IDELEMS(o->Shdl)*sizeof(int));
+    memcpy(s->fromQ,o->fromQ,IDELEMS(o->Shdl)*sizeof(int));
+  }
+  else
+    s->fromQ=NULL;
+  copyT(o,s);//s->T=...
+  s->tail = pInit();
+  copyL(o,s);//s->L=...
+  s->B=initL();
+  s->kHEdge=pCopy(o->kHEdge);
+  s->kNoether=pCopy(o->kNoether);
+  if (o->NotUsedAxis!=NULL)
+  {
+    s->NotUsedAxis=(BOOLEAN *)omAlloc(currRing->N*sizeof(BOOLEAN));
+    memcpy(s->NotUsedAxis,o->NotUsedAxis,currRing->N*sizeof(BOOLEAN));
+  }
+  s->kIdeal=NULL;
+  //s->P=s->L[s->Ll+1];
+  s->P.Init(o->tailRing);
+  s->update=o->update;
+  s->posInLOldFlag=o->posInLOldFlag;
+  s->kModW = o->kModW;
+//   if (o->kModW!=NULL)
+//     s->kModW=ivCopy(o->kModW);
+//   else
+//     s->kModW=NULL;
+  s->pairtest=NULL;
+  s->sl=o->sl;
+  s->mu=o->mu;
+  s->tl=o->tl;
+  s->tmax=o->tmax;
+  s->Ll=o->Ll;
+  s->Lmax=o->Lmax;
+  s->Bl=-1;
+  s->Bmax=setmax;
+  s->ak=o->ak;
+  s->syzComp=o->syzComp;
+  s->LazyPass=o->LazyPass;
+  s->LazyDegree=o->LazyDegree;
+  s->HCord=o->HCord;
+  s->lastAxis=o->lastAxis;
+  s->interpt=o->interpt;
+  s->homog=o->homog;
+  s->news=o->news;
+  s->newt=o->newt;
+  s->kHEdgeFound=o->kHEdgeFound;
+  s->honey=o->honey;
+  s->sugarCrit=o->sugarCrit;
+  s->Gebauer=o->Gebauer;
+  s->noTailReduction=o->noTailReduction;
+  s->fromT=o->fromT;
+  s->noetherSet=o->noetherSet;
+  kTest_TS(s);
+  return s;
+}
+
+BOOLEAN k_factorize(poly p,ideal &rfac, ideal &fac_copy)
+{
+  int facdeg=pFDeg(p);
+  ideal fac=singclap_factorize(p,NULL,1);
+  int fac_elems;
+#ifndef HAVE_LIBFAC_P
+  if (fac==NULL)
+  {
+    fac=idInit(1,1);
+    fac->m[0]=pCopy(strat->P.p);
+    fac_elems=1;
+  }
+  else
+#endif
+    fac_elems=IDELEMS(fac);
+  rfac=fac;
+  fac_copy=idInit(fac_elems,1);
+
+  if ((fac_elems!=1)||(facdeg!=pFDeg(fac->m[0])))
+  {
+    if (TEST_OPT_DEBUG)
+    {
+      Print("-> %d factors\n",fac_elems);
+    }
+    else if (TEST_OPT_PROT)
+    {
+      int ii=fac_elems;
+      if (ii>1)
+      {
+        while(ii>0) { PrintS("F"); ii--; }
+      }
+    }
+    return TRUE;
+  }
+  else
+  {
+    pDelete(&(fac->m[0]));
+    fac->m[0]=pCopy(p);
+  }
+  return FALSE;
+}
+
+static void completeReduceFac (kStrategy strat, ideal_list FL)
+{
+  int si;
+
+  strat->noTailReduction = FALSE;
+  if (TEST_OPT_PROT)
+  {
+    PrintLn();
+    if (timerv) writeTime("standard base computed:");
+  }
+  if (TEST_OPT_PROT)
+  {
+    Print("(S:%d)",strat->sl);mflush();
+  }
+  for (si=strat->sl; si>0; si--)
+  {
+    //if (strat->interpt) test_int_std(strat->kIdeal);
+    strat->S[si] = redtailBba(strat->S[si],si-1,strat);
+    if (TEST_OPT_INTSTRATEGY)
+    {
+      pCleardenom(strat->S[si]);
+    }
+    if (TEST_OPT_PROT)
+    {
+      PrintS("-");mflush();
+    }
+    ideal fac;
+    ideal fac_copy;
+
+    if (!k_factorize(strat->S[si],fac,fac_copy))
+    {
+      idDelete(&fac);
+      idDelete(&fac_copy);
+      continue;
+    }
+
+    deleteInS(si,strat);
+
+    int i;
+    for(i=IDELEMS(fac)-1;i>=0;i--)
+    {
+      kStrategy n=strat;
+      if (i>=1)
+      {
+        n=kStratCopy(strat); // includes: memset(&n->P,0,sizeof(n->P));
+        n->next=strat->next;
+        strat->next=n;
+      }
+      else
+      {
+        n->P.Init(strat->tailRing);
+      }
+
+      n->P.p=fac->m[i];
+      n->P.pLength=0;
+      n->initEcart(&n->P);
+
+      /* enter P.p into s and L */
+      int pos;
+      if (n->sl==-1) pos=0;
+      else pos=posInS(n,n->sl,n->P.p,n->P.ecart);
+      if (TEST_OPT_INTSTRATEGY)
+      {
+        n->P.p = redtailBba(n->P.p,pos-1,n);
+        pCleardenom(n->P.p);
+      }
+      else
+      {
+        pNorm(n->P.p);
+        n->P.p = redtailBba(n->P.p,pos-1,n);
+      }
+      if (TEST_OPT_DEBUG)
+      {
+        PrintS("new s:");
+        wrp(n->P.p);
+        PrintLn();
+      }
+      enterpairs(n->P.p,n->sl,n->P.ecart,pos,n);
+      enterT(n->P,n);
+      n->enterS(n->P,pos,n, n->tl);
+
+      /* construct D */
+      if (IDELEMS(fac)>1)
+      {
+        if (n->D==NULL)
+        {
+          n->D=idCopy(fac_copy);
+          idSkipZeroes(n->D);
+        }
+        else
+        {
+          idTest(n->D);
+          ideal r=idAdd(n->D,fac_copy);
+          idDelete(&n->D);
+          n->D=r;
+        }
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("new D:\n");
+          iiWriteMatrix((matrix)n->D,"D",1,0);
+          PrintLn();
+        }
+      }
+
+      fac_copy->m[i]=pCopy(fac->m[i]);
+      fac->m[i]=NULL;
+
+      /* check for empty sets */
+      if (n->D!=NULL)
+      {
+        int j=IDELEMS(n->D)-1;
+        while(j>=0)
+        {
+          if (n->D->m[j]!=NULL)
+          {
+            poly r=kNF(n->Shdl,NULL,n->D->m[j],0,TRUE);
+            if (r==NULL)
+            {
+              if (TEST_OPT_DEBUG)
+              {
+                PrintS("empty set because:");
+                wrp(n->D->m[j]);
+                PrintLn();
+                messageSets(n);
+              }
+              while (n->Ll >= 0) deleteInL(n->L,&n->Ll,n->Ll,n);
+              while (n->tl >= 0)
+              {
+                int i=n->sl;
+                while (i>=0)
+                {
+                  if (n->S[i]==n->T[n->tl].p)
+                  {
+                    n->T[n->tl].p=NULL; n->S[i]=NULL;
+                    break;
+                  }
+                  i--;
+                }
+                pDelete(&n->T[n->tl].p);
+                n->tl--;
+              }
+              memset(n->Shdl->m,0,IDELEMS(n->Shdl)*sizeof(poly));
+              n->sl=-1;
+              if (strat==n) si=-1;
+              break;
+            }
+            else
+            {
+              pDelete(&r);
+            }
+          }
+          j--;
+        }
+      }
+      /* check for empty sets */
+      {
+        ideal_list Lj=FL;
+        while (Lj!=NULL)
+        {
+          if ((n->sl>=0)&&(n->S[0]!=NULL))
+          {
+            ideal r=kNF(n->Shdl,NULL,Lj->d,0,TRUE);
+            if (idIs0(r))
+            {
+              if (TEST_OPT_DEBUG)
+              {
+                Print("empty set because:L[%x]\n",Lj);
+              }
+              while (n->Ll >= 0) deleteInL(n->L,&n->Ll,n->Ll,n);
+              while (n->tl >= 0)
+              {
+                int i=n->sl;
+                while (i>=0)
+                {
+                  if (n->S[i]==n->T[n->tl].p)
+                  {
+                    n->T[n->tl].p=NULL; n->S[i]=NULL;
+                    break;
+                  }
+                  i--;
+                }
+                pDelete(&n->T[n->tl].p);
+                n->tl--;
+              }
+              memset(n->Shdl->m,0,IDELEMS(n->Shdl)*sizeof(poly));
+              n->sl=-1;
+              if (strat==n) si=-1;
+              idDelete(&r);
+              break;
+            }
+            idDelete(&r);
+          }
+          Lj=Lj->next;
+        }
+      }
+    } /* for */
+    for(i=0;i<IDELEMS(fac);i++) fac->m[i]=NULL;
+    idDelete(&fac);
+    idDelete(&fac_copy);
+    if ((strat->Ll>=0) && (strat->sl>=0)) break;
+    else si=strat->sl+1;
+  }
+}
+
+ideal bbafac (ideal F, ideal Q,intvec *w,kStrategy strat, ideal_list FL)
+{
+  int   srmax,lrmax;
+  int   olddeg,reduc=0;
+  int red_result = 1;
+  srmax = strat->sl;
+  reduc = olddeg = lrmax = 0;
+  /* compute------------------------------------------------------- */
+  if ((strat->Ll==-1) && (strat->sl>=0))
+  {
+    if (TEST_OPT_REDSB) completeReduceFac(strat,FL);
+  }
+  kTest_TS(strat);
+  while (strat->Ll >= 0)
+  {
+    if (strat->Ll > lrmax) lrmax =strat->Ll;/*stat.*/
+    if (TEST_OPT_DEBUG) messageSets(strat);
+    //test_int_std(strat->kIdeal);
+    if (strat->Ll== 0) strat->interpt=TRUE;
+    if (TEST_OPT_DEGBOUND
+    && ((strat->honey
+        && (strat->L[strat->Ll].ecart+pFDeg(strat->L[strat->Ll].p)>Kstd1_deg))
+      || ((!strat->honey) && (pFDeg(strat->L[strat->Ll].p)>Kstd1_deg))))
+    {
+      /*
+      *stops computation if
+      * 24 IN test and the degree +ecart of L[strat->Ll] is bigger then
+      *a predefined number Kstd1_deg
+      */
+      while (strat->Ll >= 0) deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
+      break;
+    }
+    /* picks the last element from the lazyset L */
+    strat->P = strat->L[strat->Ll];
+    strat->Ll--;
+    if (pNext(strat->P.p) == strat->tail)
+    {
+      /* deletes the short spoly and computes */
+      pLmFree(strat->P.p);
+      /* the real one */
+      strat->P.p = ksOldCreateSpoly(strat->P.p1,
+                                    strat->P.p2,
+                                    strat->kNoether);
+    }
+    if (strat->honey)
+    {
+      if (TEST_OPT_PROT)
+        message(strat->P.ecart+pFDeg(strat->P.p),&olddeg,&reduc,strat, red_result);
+    }
+    else
+    {
+      if (TEST_OPT_PROT)
+        message(pFDeg(strat->P.p),&olddeg,&reduc,strat, red_result);
+    }
+    /* reduction of the element choosen from L */
+    kTest_TS(strat);
+    red_result = strat->red(&strat->P,strat);
+    if (strat->P.p != NULL)
+    {
+      /* statistic */
+      if (TEST_OPT_PROT) PrintS("s");
+      ideal fac;
+      ideal fac_copy;
+
+      if (!k_factorize(strat->P.p,fac,fac_copy))
+      {
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          strat->P.p = redtailBba(strat->P.p,strat->sl,strat);
+          if (strat->redTailChange) pCleardenom(strat->P.p);
+        }
+        else
+        {
+          pNorm(strat->P.p);
+          strat->P.p = redtailBba(strat->P.p,strat->sl,strat);
+        }
+        if (strat->redTailChange)
+        {
+          idDelete(&fac);
+          idDelete(&fac_copy);
+          if (!k_factorize(strat->P.p,fac,fac_copy))
+          {
+            pDelete(&(fac->m[0]));
+            fac->m[0]=strat->P.p;
+            strat->P.p=NULL;
+          }
+          else
+          {
+            pDelete(&strat->P.p);
+          }
+        }
+      }
+      if (strat->P.lcm!=NULL) pLmFree(strat->P.lcm);
+      int i;
+
+      for(i=IDELEMS(fac)-1;i>=0;i--)
+      {
+        int ii;
+        kStrategy n=strat;
+        if (i>=1)
+        {
+          n=kStratCopy(strat); // includes memset(&n->P,0,sizeof(n->P));
+          kTest_TS(n);
+          n->next=strat->next;
+          strat->next=n;
+        }
+        else
+        {
+          n->P.Init(strat->tailRing);
+        }
+
+        n->P.p=fac->m[i];
+        n->initEcart(&n->P);
+        kTest_TS(n);
+
+        /* enter P.p into s and L */
+        int pos;
+        if (n->sl==-1) pos=0;
+        else pos=posInS(n,n->sl,n->P.p,n->P.ecart);
+
+        // we have already reduced all elements from fac....
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          n->P.p = redtailBba(n->P.p,pos-1,n);
+          if (n->redTailChange) pCleardenom(n->P.p);
+        }
+        else
+        {
+          pNorm(n->P.p);
+          n->P.p = redtailBba(n->P.p,pos-1,n);
+        }
+        kTest_TS(n);
+
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("new s:");
+          wrp(n->P.p);
+          PrintLn();
+        }
+        enterpairs(n->P.p,n->sl,n->P.ecart,pos,n);
+        enterT(n->P,n);
+        n->enterS(n->P,pos,n, n->tl);
+        {
+          int i=n->Ll;
+          for(;i>=0;i--)
+          {
+            n->L[i].i_r1= -1;
+            for(ii=0; ii<=n->tl; ii++)
+            {
+              if (n->R[ii]->p==n->L[i].p1)  { n->L[i].i_r1=ii;break; }
+            }
+            n->L[i].i_r2= -1;
+            for(ii=0; ii<=n->tl; ii++)
+            {
+              if (n->R[ii]->p==n->L[i].p2)  { n->L[i].i_r2=ii;break; }
+            }
+          }
+        }
+        kTest_TS(n);
+        if (n->sl>srmax) srmax = n->sl;
+
+        /* construct D */
+        if (IDELEMS(fac)>1)
+        {
+          if (n->D==NULL)
+          {
+            n->D=idCopy(fac_copy);
+            idSkipZeroes(n->D);
+          }
+          else
+          {
+            idTest(n->D);
+            ideal r=idAdd(n->D,fac_copy);
+            idDelete(&n->D);
+            n->D=r;
+          }
+          if (TEST_OPT_DEBUG)
+          {
+            PrintS("new D:\n");
+            iiWriteMatrix((matrix)n->D,"D",1,0);
+            PrintLn();
+          }
+        }
+
+        fac_copy->m[i]=pCopy(fac->m[i]);
+        fac->m[i]=NULL;
+
+        /* check for empty sets */
+        if (n->D!=NULL)
+        {
+          int j=IDELEMS(n->D)-1;
+          while(j>=0)
+          {
+            if (n->D->m[j]!=NULL)
+            {
+              poly r=kNF(n->Shdl,NULL,n->D->m[j],0,TRUE);
+              if (r==NULL)
+              {
+                if (TEST_OPT_DEBUG)
+                {
+                  PrintS("empty set because:");
+                  wrp(n->D->m[j]);
+                  PrintLn();
+                  messageSets(n);
+                }
+                //if (n->Ll >=0) Print("Ll:%d|",n->Ll);
+                while (n->Ll >= 0) deleteInL(n->L,&n->Ll,n->Ll,n);
+                //if (n->tl >=0) Print("tl:%d|",n->tl);
+                while (n->tl >= 0)
+                {
+                  int i=n->sl;
+                  while (i>=0)
+                  {
+                    if (n->S[i]==n->T[n->tl].p)
+                    {
+                      n->T[n->tl].p=NULL; n->S[i]=NULL;
+                      break;
+                    }
+                    i--;
+                  }
+                  pDelete(&n->T[n->tl].p);
+                  n->tl--;
+                }
+                memset(n->Shdl->m,0,IDELEMS(n->Shdl)*sizeof(poly));
+                n->sl=-1;
+                break;
+              }
+              else
+              {
+                pDelete(&r);
+              }
+            }
+            j--;
+          }
+        }
+
+        /* check for empty sets */
+        {
+          ideal_list Lj=FL;
+          while (Lj!=NULL)
+          {
+            if ((n->sl>=0)&&(n->S[0]!=NULL))
+            {
+              ideal r=kNF(n->Shdl,NULL,Lj->d,0,TRUE);
+              if (idIs0(r))
+              {
+                if (TEST_OPT_DEBUG)
+                {
+                  Print("empty set because:L[%x]\n",Lj);
+                }
+                while (n->Ll >= 0) deleteInL(n->L,&n->Ll,n->Ll,n);
+                while (n->tl >= 0)
+                {
+                  int i=n->sl;
+                  while (i>=0)
+                  {
+                    if (n->S[i]==n->T[n->tl].p)
+                    {
+                      n->T[n->tl].p=NULL; n->S[i]=NULL;
+                      break;
+                    }
+                    i--;
+                  }
+                  pDelete(&n->T[n->tl].p);
+                  n->tl--;
+                }
+                memset(n->Shdl->m,0,IDELEMS(n->Shdl)*sizeof(poly));
+                n->sl=-1;
+                idDelete(&r);
+                break;
+              }
+              idDelete(&r);
+            }
+            Lj=Lj->next;
+          }
+        }
+      } /* for */
+      for(i=0;i<IDELEMS(fac);i++) fac->m[i]=NULL;
+      idDelete(&fac);
+      idDelete(&fac_copy);
+    }
+#ifdef KDEBUG
+    strat->P.lcm=NULL;
+#endif
+    kTest_TS(strat);
+    if ((strat->Ll==-1) && (strat->sl>=0))
+    {
+      if (TEST_OPT_REDSB) completeReduceFac(strat,FL);
+    }
+    kTest_TS(strat);
+  }
+  if (TEST_OPT_DEBUG) messageSets(strat);
+  /* complete reduction of the standard basis--------- */
+  /* release temp data-------------------------------- */
+  exitBuchMora(strat);
+  if (TEST_OPT_WEIGHTM)
+  {
+    pRestoreDegProcs(pFDegOld, pLDegOld);
+    if (ecartWeights)
+    {
+      omFreeSize((ADDRESS)ecartWeights,(pVariables+1)*sizeof(short));
+      ecartWeights=NULL;
+    }
+  }
+  if (TEST_OPT_PROT) messageStat(srmax,lrmax,0,strat);
+  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
+  return (strat->Shdl);
+}
+#endif
+
+ideal_list kStdfac(ideal F, ideal Q, tHomog h,intvec ** w,ideal D)
+{
+#ifdef HAVE_FACTORY
+  ideal r;
+  BOOLEAN b=pLexOrder,toReset=FALSE;
+  BOOLEAN delete_w=(w==NULL);
+  kStrategy strat=new skStrategy;
+  kStrategy orgstrat=strat;
+  ideal_list L=NULL;
+
+  if (rField_has_simple_inverse())
+    strat->LazyPass=20;
+  else
+    strat->LazyPass=2;
+  strat->LazyDegree = 1;
+  strat->ak = idRankFreeModule(F);
+  if ((h==testHomog))
+  {
+    if (strat->ak==0)
+    {
+      h = (tHomog)idHomIdeal(F,Q);
+      w=NULL;
+    }
+    else
+      h = (tHomog)idHomModule(F,Q,w);
+  }
+  if (h==isHomog)
+  {
+    if ((w!=NULL) && (*w!=NULL))
+    {
+      kModW = *w;
+      strat->kModW = *w;
+      pFDegOld = pFDeg;
+      pLDegOld = pLDeg;
+      pSetDegProcs(kModDeg);
+      toReset = TRUE;
+    }
+    pLexOrder = TRUE;
+    strat->LazyPass*=2;
+  }
+  strat->homog=h;
+  initBuchMoraCrit(strat); /*set Gebauer, honey, sugarCrit*/
+  initBuchMoraPos(strat);
+  initBba(F,strat);
+  initBuchMora(F, Q,strat);
+  if (D!=NULL)
+  {
+    strat->D=idCopy(D);
+  }
+// Ende der Initalisierung
+  while (strat!=NULL)
+  {
+    if (TEST_OPT_DEBUG)
+      PrintS("====================================\n");
+    if (w!=NULL)
+      r=bbafac(F,Q,*w,strat,L);
+    else
+      r=bbafac(F,Q,NULL,strat,L);
+#ifdef KDEBUG
+    int i;
+    for (i=0; i<IDELEMS(r); i++) pTest(r->m[i]);
+#endif
+    idSkipZeroes(r);
+    // Testausgabe:
+    //if (!idIs0(r))
+    //{
+    //  PrintS("===================================================\n");
+    //  iiWriteMatrix((matrix)r,"S",1,0);
+    //  PrintS("\n===================================================\n");
+    //}
+    //else
+    //{
+    //  PrintS("=========empty============================\n");
+    //}
+    strat=strat->next;
+    if(!idIs0(r))
+    {
+      ideal_list LL=(ideal_list)omAlloc(sizeof(*LL));
+      LL->d=r;
+      LL->next=L;
+      L=LL;
+    }
+  }
+  /* check for empty sets */
+  {
+    ideal_list Lj=L->next;
+    ideal_list Lj_prev=L;
+    while (Lj!=NULL)
+    {
+      ideal_list Li=L;
+      while(Li!=Lj)
+      {
+        ideal r=kNF(Lj->d,NULL,Li->d,0,TRUE);
+        if (idIs0(r))
+        {
+          if (TEST_OPT_DEBUG)
+          {
+            Print("empty set L[%x] because:L[%x]\n",Lj,Li);
+          }
+          // delete L[j],
+          Li=L; 
+          if (Lj_prev!=NULL)
+          {
+            Lj=Lj_prev;
+            if (Lj==L) Lj_prev=NULL;
+            else
+            {
+              Lj_prev=L;
+              while(Lj_prev->next!=Lj) Lj_prev=Lj_prev->next;
+            }
+          }
+          else Lj=NULL;
+        }
+        else
+        {
+          Li=Li->next;
+        }
+        idDelete (&r);
+      }
+      if (Lj!=NULL) Lj=Lj->next;
+    }
+  }
+// Ende: aufraeumen
+  if (toReset)
+  {
+    pRestoreDegProcs(pFDegOld, pLDegOld);
+    kModW = NULL;
+  }
+  pLexOrder = b;
+  delete(strat);
+  strat=orgstrat;
+  while (strat!=NULL)
+  {
+    orgstrat=strat->next;
+    delete(strat);
+    strat=orgstrat;
+  }
+  if ((delete_w)&&(w!=NULL)&&(*w!=NULL)) delete *w;
+  return L;
+#else
+  return NULL;
+#endif
+}
Index: kernel/kstdfac.h
===================================================================
--- kernel/kstdfac.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/kstdfac.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,14 @@
+#ifndef KSTDFAC_H
+#define KSTDFAC_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: kstdfac.h,v 1.1.1.1 2003-10-06 12:15:56 Singular Exp $ */
+/*
+*  ABSTRACT -  Kernel: factorizing alg. of Buchberger
+*/
+#include "structs.h"
+
+ideal_list kStdfac(ideal F, ideal Q, tHomog h,intvec ** w, ideal D=NULL);
+#endif
+
Index: kernel/kutil.cc
===================================================================
--- kernel/kutil.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/kutil.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,4601 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: kutil.cc,v 1.1.1.1 2003-10-06 12:15:54 Singular Exp $ */
+/*
+* ABSTRACT: kernel: utils for kStd
+*/
+
+#ifndef KUTIL_CC
+#define KUTIL_CC
+
+// #define PDEBUG 2
+// #define PDIV_DEBUG
+#include <stdlib.h>
+#include <string.h>
+#include "mod2.h"
+#include <mylimits.h>
+#include "structs.h"
+#ifdef HAVE_PLURAL
+#include "gring.h"
+#endif
+#ifdef KDEBUG
+#undef KDEBUG
+#define KDEBUG 2
+#endif
+
+// define if enterL, enterT should use memmove instead of doing it manually
+// on topgun, this is slightly faster (see monodromy_l.tst, homog_gonnet.sing)
+#ifndef SunOS_4
+#define ENTER_USE_MEMMOVE
+#endif
+
+// define, if the my_memmove inlines should be used instead of
+// system memmove -- it does not seem to pay off, though
+// #define ENTER_USE_MYMEMMOVE
+
+#include "kutil.h"
+#include "febase.h"
+#include "omalloc.h"
+#include "numbers.h"
+#include "polys.h"
+#include "ring.h"
+#include "ideals.h"
+#include "timer.h"
+#include "cntrlc.h"
+#include "stairc.h"
+#include "kstd1.h"
+#include "pShallowCopyDelete.h"
+
+#ifdef KDEBUG
+#undef KDEBUG
+#define KDEBUG 2
+#endif
+
+#ifdef ENTER_USE_MYMEMMOVE
+inline void _my_memmove_d_gt_s(unsigned long* d, unsigned long* s, long l)
+{
+  register unsigned long* _dl = (unsigned long*) d;
+  register unsigned long* _sl = (unsigned long*) s;
+  register long _i = l - 1;
+
+  do
+  {
+    _dl[_i] = _sl[_i];
+    _i--;
+  }
+  while (_i >= 0);
+}
+
+inline void _my_memmove_d_lt_s(unsigned long* d, unsigned long* s, long l)
+{
+  register long _ll = l;
+  register unsigned long* _dl = (unsigned long*) d;
+  register unsigned long* _sl = (unsigned long*) s;
+  register long _i = 0;
+
+  do
+  {
+    _dl[_i] = _sl[_i];
+    _i++;
+  }
+  while (_i < _ll);
+}
+
+inline void _my_memmove(void* d, void* s, long l)
+{
+  unsigned long _d = (unsigned long) d;
+  unsigned long _s = (unsigned long) s;
+  unsigned long _l = ((l) + SIZEOF_LONG - 1) >> LOG_SIZEOF_LONG;
+
+  if (_d > _s) _my_memmove_d_gt_s(_d, _s, _l);
+  else _my_memmove_d_lt_s(_d, _s, _l);
+}
+
+#undef memmove
+#define memmove(d,s,l) _my_memmove(d, s, l)
+#endif
+
+
+static poly redMora (poly h,int maxIndex,kStrategy strat);
+static poly redBba (poly h,int maxIndex,kStrategy strat);
+
+static inline int pDivComp(poly p, poly q)
+{
+  if (pGetComp(p) == pGetComp(q))
+  {
+    BOOLEAN a=FALSE, b=FALSE;
+    int i;
+    unsigned long la, lb;
+    unsigned long divmask = currRing->divmask;
+    for (i=0; i<currRing->VarL_Size; i++)
+    {
+      la = p->exp[currRing->VarL_Offset[i]];
+      lb = q->exp[currRing->VarL_Offset[i]];
+      if (la != lb)
+      {
+        if (la < lb)
+        {
+          if (b) return 0;
+          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
+            return 0;
+          a = TRUE;
+        }
+        else
+        {
+          if (a) return 0;
+          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
+            return 0;
+          b = TRUE;
+        }
+      }
+    }
+    if (a) return 1;
+    if (b) return -1;
+  }
+  return 0;
+}
+
+
+BITSET  test=(BITSET)0;
+int     HCord;
+int     Kstd1_deg;
+int     mu=32000;
+
+/*2
+*deletes higher monomial of p, re-compute ecart and length
+*works only for orderings with ecart =pFDeg(end)-pFDeg(start)
+*/
+void deleteHC(LObject *L, kStrategy strat, BOOLEAN fromNext)
+{
+  if (strat->kHEdgeFound)
+  {
+    kTest_L(L);
+    poly p1;
+    poly p = L->GetLmTailRing();
+    int l = 1;
+    kBucket_pt bucket = NULL;
+    if (L->bucket != NULL)
+    {
+      kBucketClear(L->bucket, &pNext(p), &L->pLength);
+      L->pLength++;
+      bucket = L->bucket;
+      L->bucket = NULL;
+      L->last = NULL;
+    }
+
+    if (!fromNext && p_Cmp(p,strat->kNoetherTail(), L->tailRing) == -1)
+    {
+      L->Delete();
+      L->Clear();
+      L->ecart = -1;
+      if (bucket != NULL) kBucketDestroy(&bucket);
+      return;
+    }
+    p1 = p;
+    while (pNext(p1)!=NULL)
+    {
+      if (p_LmCmp(pNext(p1), strat->kNoetherTail(), L->tailRing) == -1)
+      {
+        L->last = p1;
+        p_Delete(&pNext(p1), L->tailRing);
+        if (p1 == p)
+        {
+          if (L->t_p != NULL)
+          {
+            assume(L->p != NULL && p == L->t_p);
+            pNext(L->p) = NULL;
+          }
+          L->max  = NULL;
+        }
+        else if (fromNext)
+          L->max  = p_GetMaxExpP(pNext(L->p), L->tailRing ); // p1;
+        if (L->pLength != 0) L->pLength = l;
+        // Hmmm when called from updateT, then only
+        // reset ecart when cut
+        if (fromNext)
+          L->ecart = L->pLDeg() - L->GetpFDeg();
+        break;
+      }
+      l++;
+      pIter(p1);
+    }
+    if (! fromNext)
+    {
+      L->SetpFDeg();
+      L->ecart = L->pLDeg(strat->LDegLast) - L->GetpFDeg();
+    }
+    if (bucket != NULL)
+    {
+      if (L->pLength > 1)
+      {
+        kBucketInit(bucket, pNext(p), L->pLength - 1);
+        pNext(p) = NULL;
+        if (L->t_p != NULL) pNext(L->t_p) = NULL;
+        L->pLength = 0;
+        L->bucket = bucket;
+        L->last = NULL;
+      }
+      else
+        kBucketDestroy(&bucket);
+    }
+    kTest_L(L);
+  }
+}
+
+void deleteHC(poly* p, int* e, int* l,kStrategy strat)
+{
+  LObject L(*p, currRing, strat->tailRing);
+
+  deleteHC(&L, strat);
+  *p = L.p;
+  *e = L.ecart;
+  *l = L.length;
+  if (L.t_p != NULL) p_LmFree(L.t_p, strat->tailRing);
+}
+
+/*2
+*tests if p.p=monomial*unit and cancels the unit
+*/
+void cancelunit (LObject* L)
+{
+  int  i;
+  poly h;
+
+  if(currRing->OrdSgn != -1) return;
+  if(TEST_OPT_CANCELUNIT) return;
+
+  ring r = L->tailRing;
+  poly p = L->GetLmTailRing();
+
+  if(p_GetComp(p, r) != 0 && !p_OneComp(p, r)) return;
+
+  if (L->ecart != 0)
+  {
+//    for(i=r->N;i>0;i--)
+//    {
+//      if ((p_GetExp(p,i,r)>0) && (rIsPolyVar(i, r)==TRUE)) return;
+//    }
+    h = pNext(p);
+    loop
+    {
+      if (h==NULL)
+      {
+        p_Delete(&pNext(p), r);
+        number eins=nInit(1);
+        if (L->p != NULL)  pSetCoeff(L->p,eins);
+        else if (L->t_p != NULL) nDelete(&pGetCoeff(L->t_p));
+        if (L->t_p != NULL) pSetCoeff0(L->t_p,eins);
+        L->ecart = 0;
+        L->length = 1;
+        if (L->pLength > 0) L->pLength = 1;
+        if (L->last != NULL) L->last = p;
+
+        if (L->t_p != NULL && pNext(L->t_p) != NULL)
+          pNext(L->t_p) = NULL;
+        if (L->p != NULL && pNext(L->p) != NULL)
+          pNext(L->p) = NULL;
+        return;
+      }
+      i = 0;
+      loop
+      {
+        i++;
+        if (p_GetExp(p,i,r) > p_GetExp(h,i,r)) return ; // does not divide
+        if (i == r->N) break; // does divide, try next monom
+      }
+      pIter(h);
+    }
+  }
+}
+
+/*2
+*pp is the new element in s
+*returns TRUE (in strat->kHEdgeFound) if
+*-HEcke is allowed
+*-we are in the last componente of the vector
+*-on all axis are monomials (all elements in NotUsedAxis are FALSE)
+*returns FALSE for pLexOrderings,
+*assumes in module case an ordering of type c* !!
+* HEckeTest is only called with strat->kHEdgeFound==FALSE !
+*/
+void HEckeTest (poly pp,kStrategy strat)
+{
+  int   j,k,p;
+
+  strat->kHEdgeFound=FALSE;
+  if (pLexOrder || currRing->MixedOrder)
+  {
+    return;
+  }
+  if (strat->ak > 1)           /*we are in the module case*/
+  {
+    return; // until ....
+    //if (!pVectorOut)     /*pVectorOut <=> order = c,* */
+    //  return FALSE;
+    //if (pGetComp(pp) < strat->ak) /* ak is the number of the last component */
+    //  return FALSE;
+  }
+  k = 0;
+  p=pIsPurePower(pp);
+  if (p!=0) strat->NotUsedAxis[p] = FALSE;
+  /*- the leading term of pp is a power of the p-th variable -*/
+  for (j=pVariables;j>0; j--)
+  {
+    if (strat->NotUsedAxis[j])
+    {
+      return;
+    }
+  }
+  strat->kHEdgeFound=TRUE;
+}
+
+/*2
+*utilities for TSet, LSet
+*/
+inline static intset initec (const int maxnr)
+{
+  return (intset)omAlloc(maxnr*sizeof(int));
+}
+
+inline static unsigned long* initsevS (const int maxnr)
+{
+  return (unsigned long*)omAlloc0(maxnr*sizeof(unsigned long));
+}
+inline static int* initS_2_R (const int maxnr)
+{
+  return (int*)omAlloc0(maxnr*sizeof(int));
+}
+
+static inline void enlargeT (TSet &T, TObject** &R, unsigned long* &sevT,
+                             int &length, const int incr)
+{
+  assume(T!=NULL);
+  assume(sevT!=NULL);
+  assume(R!=NULL);
+  assume((length+incr) > 0);
+
+  int i;
+  T = (TSet)omRealloc0Size(T, length*sizeof(TObject),
+                           (length+incr)*sizeof(TObject));
+
+  sevT = (unsigned long*) omReallocSize(sevT, length*sizeof(long*),
+                           (length+incr)*sizeof(long*));
+
+  R = (TObject**)omRealloc0Size(R,length*sizeof(TObject*),
+                                (length+incr)*sizeof(TObject*));
+  for (i=length-1;i>=0;i--) R[T[i].i_r] = &(T[i]);
+  length += incr;
+}
+
+void cleanT (kStrategy strat)
+{
+  int i,j;
+  poly  p;
+  assume(currRing == strat->tailRing || strat->tailRing != NULL);
+
+  pShallowCopyDeleteProc p_shallow_copy_delete =
+    (strat->tailRing != currRing ?
+     pGetShallowCopyDeleteProc(strat->tailRing, currRing) :
+     NULL);
+
+  for (j=0; j<=strat->tl; j++)
+  {
+    p = strat->T[j].p;
+    strat->T[j].p=NULL;
+    if (strat->T[j].max != NULL)
+      p_LmFree(strat->T[j].max, strat->tailRing);
+    i = -1;
+    loop
+    {
+      i++;
+      if (i>strat->sl)
+      {
+        if (strat->T[j].t_p != NULL)
+        {
+          p_Delete(&(strat->T[j].t_p), strat->tailRing);
+          p_LmFree(p, currRing);
+        }
+        else
+          pDelete(&p);
+        break;
+      }
+      if (p == strat->S[i])
+      {
+        if (strat->T[j].t_p != NULL)
+        {
+          assume(p_shallow_copy_delete != NULL);
+          pNext(p) = p_shallow_copy_delete(pNext(p),strat->tailRing,currRing,
+                                           currRing->PolyBin);
+          p_LmFree(strat->T[j].t_p, strat->tailRing);
+        }
+        break;
+      }
+    }
+  }
+  strat->tl=-1;
+}
+
+LSet initL ()
+{
+  int i;
+  LSet l = (LSet)omAlloc(setmaxL*sizeof(LObject));
+  for (i=setmaxL-1;i>=0;i--)
+  {
+    l[i].tailRing = currRing;
+    l[i].i_r1 = -1;
+    l[i].i_r2 = -1;
+    l[i].i_r = -1;
+  }
+  return l;
+}
+
+static inline void enlargeL (LSet* L,int* length,const int incr)
+{
+  assume((*L)!=NULL);
+  assume((length+incr)>0);
+
+  *L = (LSet)omReallocSize((*L),(*length)*sizeof(LObject),
+                                   ((*length)+incr)*sizeof(LObject));
+  (*length) += incr;
+}
+
+void initPairtest(kStrategy strat)
+{
+  strat->pairtest = (BOOLEAN *)omAlloc0((strat->sl+2)*sizeof(BOOLEAN));
+}
+
+/*2
+*test whether (p1,p2) or (p2,p1) is in L up position length
+*it returns TRUE if yes and the position k
+*/
+BOOLEAN isInPairsetL(int length,poly p1,poly p2,int*  k,kStrategy strat)
+{
+  LObject *p=&(strat->L[length]);
+
+  *k = length;
+  loop
+  {
+    if ((*k) < 0) return FALSE;
+    if (((p1 == (*p).p1) && (p2 == (*p).p2))
+    ||  ((p1 == (*p).p2) && (p2 == (*p).p1)))
+      return TRUE;
+    (*k)--;
+    p--;
+  }
+}
+
+/*2
+*in B all pairs have the same element p on the right
+*it tests whether (q,p) is in B and returns TRUE if yes
+*and the position k
+*/
+BOOLEAN isInPairsetB(poly q,int*  k,kStrategy strat)
+{
+  LObject *p=&(strat->B[strat->Bl]);
+
+  *k = strat->Bl;
+  loop
+  {
+    if ((*k) < 0) return FALSE;
+    if (q == (*p).p1)
+      return TRUE;
+    (*k)--;
+    p--;
+  }
+}
+
+int kFindInT(poly p, TSet T, int tlength)
+{
+  int i;
+
+  for (i=0; i<=tlength; i++)
+  {
+    if (T[i].p == p) return i;
+  }
+  return -1;
+}
+
+int kFindInT(poly p, kStrategy strat)
+{
+  int i;
+  do
+  {
+    i = kFindInT(p, strat->T, strat->tl);
+    if (i >= 0) return i;
+    strat = strat->next;
+  }
+  while (strat != NULL);
+  return -1;
+}
+
+#ifdef KDEBUG
+
+void sTObject::wrp()
+{
+  if (t_p != NULL) p_wrp(t_p, tailRing);
+  else if (p != NULL) p_wrp(p, currRing, tailRing);
+  else ::wrp(NULL);
+}
+
+#define kFalseReturn(x) do { if (!x) return FALSE;} while (0)
+
+// check that Lm's of a poly from T are "equal"
+static const char* kTest_LmEqual(poly p, poly t_p, ring tailRing)
+{
+  int i;
+  for (i=1; i<=tailRing->N; i++)
+  {
+    if (p_GetExp(p, i, currRing) != p_GetExp(t_p, i, tailRing))
+      return "Lm[i] different";
+  }
+  if (p_GetComp(p, currRing) != p_GetComp(t_p, tailRing))
+    return "Lm[0] different";
+  if (pNext(p) != pNext(t_p))
+    return "Lm.next different";
+  if (pGetCoeff(p) != pGetCoeff(t_p))
+    return "Lm.coeff different";
+  return NULL;
+}
+
+static BOOLEAN sloppy_max = FALSE;
+BOOLEAN kTest_T(TObject * T, ring strat_tailRing, int i, char TN)
+{
+  ring tailRing = T->tailRing;
+  if (strat_tailRing == NULL) strat_tailRing = tailRing;
+  r_assume(strat_tailRing == tailRing);
+
+  poly p = T->p;
+  ring r = currRing;
+
+  if (T->p == NULL && T->t_p == NULL && i >= 0)
+    return dReportError("%c[%d].poly is NULL", TN, i);
+
+  if (T->tailRing != currRing)
+  {
+    if (T->t_p == NULL && i > 0)
+      return dReportError("%c[%d].t_p is NULL", TN, i);
+    pFalseReturn(p_Test(T->t_p, T->tailRing));
+    if (T->p != NULL) pFalseReturn(p_LmTest(T->p, currRing));
+    if (T->p != NULL && T->t_p != NULL)
+    {
+      const char* msg = kTest_LmEqual(T->p, T->t_p, T->tailRing);
+      if (msg != NULL)
+        return dReportError("%c[%d] %s", TN, i, msg);
+      r = T->tailRing;
+      p = T->t_p;
+    }
+    if (T->p == NULL)
+    {
+      p = T->t_p;
+      r = T->tailRing;
+    }
+    if (T->t_p != NULL && i >= 0 && TN == 'T')
+    {
+      if (pNext(T->t_p) == NULL)
+      {
+        if (T->max != NULL)
+          return dReportError("%c[%d].max is not NULL as it should be", TN, i);
+      }
+      else
+      {
+        if (T->max == NULL)
+          return dReportError("%c[%d].max is NULL", TN, i);
+        if (pNext(T->max) != NULL)
+          return dReportError("pNext(%c[%d].max) != NULL", TN, i);
+
+        pFalseReturn(p_CheckPolyRing(T->max, tailRing));
+        omCheckBinAddrSize(T->max, (tailRing->PolyBin->sizeW)*SIZEOF_LONG);
+#if KDEBUG > 0
+        if (! sloppy_max)
+        {
+          poly test_max = p_GetMaxExpP(pNext(T->t_p), tailRing);
+          p_Setm(T->max, tailRing);
+          p_Setm(test_max, tailRing);
+          BOOLEAN equal = p_ExpVectorEqual(T->max, test_max, tailRing);
+          if (! equal)
+            return dReportError("%c[%d].max out of sync", TN, i);
+          p_LmFree(test_max, tailRing);
+        }
+#endif
+      }
+    }
+  }
+  else
+  {
+    if (T->max != NULL)
+      return dReportError("%c[%d].max != NULL but tailRing == currRing",TN,i);
+    if (T->t_p != NULL)
+      return dReportError("%c[%d].t_p != NULL but tailRing == currRing",TN,i);
+    if (T->p == NULL && i > 0)
+      return dReportError("%c[%d].p is NULL", TN, i);
+    pFalseReturn(p_Test(T->p, currRing));
+  }
+
+  if (i >= 0 && T->pLength != 0 && T->pLength != pLength(p))
+  {
+    return dReportError("%c[%d] pLength error: has %d, specified to have %d",
+                        TN, i , pLength(p), T->pLength);
+  }
+
+  // check FDeg,  for elements in L and T
+  if (i >= 0 && (TN == 'T' || TN == 'L'))
+  {
+    // FDeg has ir element from T of L set
+    if (T->FDeg  != T->pFDeg())
+      return dReportError("%c[%d] FDeg error: has %d, specified to have %d",
+                          TN, i , T->pFDeg(), T->FDeg);
+  }
+
+  // check is_normalized for elements in T
+  if (i >= 0 && TN == 'T')
+  {
+    if (T->is_normalized && ! nIsOne(pGetCoeff(p)))
+      return dReportError("T[%d] is_normalized error", i);
+
+  }
+  return TRUE;
+}
+
+BOOLEAN kTest_L(LObject *L, ring strat_tailRing,
+                BOOLEAN testp, int lpos, TSet T, int tlength)
+{
+  if (testp)
+  {
+    poly pn = NULL;
+    if (L->bucket != NULL)
+    {
+      kFalseReturn(kbTest(L->bucket));
+      r_assume(L->bucket->bucket_ring == L->tailRing);
+      if (L->p != NULL && pNext(L->p) != NULL)
+      {
+        pn = pNext(L->p);
+        pNext(L->p) = NULL;
+      }
+    }
+    kFalseReturn(kTest_T(L, strat_tailRing, lpos, 'L'));
+    if (pn != NULL)
+      pNext(L->p) = pn;
+
+    ring r;
+    poly p;
+    L->GetLm(p, r);
+    if (L->sev != 0 && p_GetShortExpVector(p, r) != L->sev)
+    {
+      return dReportError("L[%d] wrong sev: has %o, specified to have %o",
+                          lpos, p_GetShortExpVector(p, r), L->sev);
+    }
+    if (lpos > 0 && L->last != NULL && pLast(p) != L->last)
+    {
+      return dReportError("L[%d] last wrong: has %p specified to have %p",
+                          lpos, pLast(p), L->last);
+    }
+  }
+  if (L->p1 == NULL)
+  {
+    // L->p2 either NULL or "normal" poly
+    pFalseReturn(pp_Test(L->p2, currRing, L->tailRing));
+  }
+  else if (tlength > 0 && T != NULL)
+  {
+    // now p1 and p2 must be != NULL and must be contained in T
+    int i;
+    i = kFindInT(L->p1, T, tlength);
+    if (i < 0)
+      return dReportError("L[%d].p1 not in T",lpos);
+    i = kFindInT(L->p2, T, tlength);
+    if (i < 0)
+      return dReportError("L[%d].p2 not in T",lpos);
+  }
+  return TRUE;
+}
+
+BOOLEAN kTest (kStrategy strat)
+{
+  int i;
+
+  // test P
+  kFalseReturn(kTest_L(&(strat->P), strat->tailRing,
+                       (strat->P.p != NULL && pNext(strat->P.p)!=strat->tail),
+                       -1, strat->T, strat->tl));
+
+  // test T
+  if (strat->T != NULL)
+  {
+    for (i=0; i<=strat->tl; i++)
+    {
+      kFalseReturn(kTest_T(&(strat->T[i]), strat->tailRing, i, 'T'));
+      if (strat->sevT[i] != pGetShortExpVector(strat->T[i].p))
+        return dReportError("strat->sevT[%d] out of sync", i);
+    }
+  }
+
+  // test L
+  if (strat->L != NULL)
+  {
+    for (i=0; i<=strat->Ll; i++)
+    {
+      kFalseReturn(kTest_L(&(strat->L[i]), strat->tailRing,
+                           strat->L[i].Next() != strat->tail, i,
+                           strat->T, strat->tl));
+      if (strat->use_buckets && strat->L[i].Next() != strat->tail &&
+          strat->L[i].Next() != NULL && strat->L[i].p1 != NULL)
+      {
+        assume(strat->L[i].bucket != NULL);
+      }
+    }
+  }
+
+  // test S
+  if (strat->S != NULL)
+    kFalseReturn(kTest_S(strat));
+
+  return TRUE;
+}
+
+BOOLEAN kTest_S(kStrategy strat)
+{
+  int i;
+  BOOLEAN ret = TRUE;
+  for (i=0; i<=strat->sl; i++)
+  {
+    if (strat->S[i] != NULL &&
+        strat->sevS[i] != pGetShortExpVector(strat->S[i]))
+    {
+      return dReportError("S[%d] wrong sev: has %o, specified to have %o",
+                          i , pGetShortExpVector(strat->S[i]), strat->sevS[i]);
+    }
+  }
+  return ret;
+}
+
+
+
+BOOLEAN kTest_TS(kStrategy strat)
+{
+  int i, j;
+  BOOLEAN ret = TRUE;
+  kFalseReturn(kTest(strat));
+
+  // test strat->R, strat->T[i].i_r
+  for (i=0; i<=strat->tl; i++)
+  {
+    if (strat->T[i].i_r < 0 || strat->T[i].i_r > strat->tl)
+      return dReportError("strat->T[%d].i_r == %d out of bounds", i,
+                          strat->T[i].i_r);
+    if (strat->R[strat->T[i].i_r] != &(strat->T[i]))
+      return dReportError("T[%d].i_r with R out of sync", i);
+  }
+  // test containment of S inT
+  if (strat->S != NULL)
+  {
+    for (i=0; i<=strat->sl; i++)
+    {
+      j = kFindInT(strat->S[i], strat->T, strat->tl);
+      if (j < 0)
+        return dReportError("S[%d] not in T", i);
+      if (strat->S_2_R[i] != strat->T[j].i_r)
+        return dReportError("S_2_R[%d]=%d != T[%d].i_r=%d\n",
+                            i, strat->S_2_R[i], j, strat->T[j].i_r);
+    }
+  }
+  // test strat->L[i].i_r1
+  for (i=0; i<=strat->Ll; i++)
+  {
+    if (strat->L[i].p1 != NULL && strat->L[i].p2)
+    {
+      if (strat->L[i].i_r1 < 0 ||
+          strat->L[i].i_r1 > strat->tl ||
+          strat->L[i].T_1(strat)->p != strat->L[i].p1)
+        return dReportError("L[%d].i_r1 out of sync", i);
+      if (strat->L[i].i_r2 < 0 ||
+          strat->L[i].i_r2 > strat->tl ||
+          strat->L[i].T_2(strat)->p != strat->L[i].p2);
+    }
+    else
+    {
+      if (strat->L[i].i_r1 != -1)
+        return dReportError("L[%d].i_r1 out of sync", i);
+      if (strat->L[i].i_r2 != -1)
+        return dReportError("L[%d].i_r2 out of sync", i);
+    }
+    if (strat->L[i].i_r != -1)
+      return dReportError("L[%d].i_r out of sync", i);
+  }
+  return TRUE;
+}
+
+#endif // KDEBUG
+
+/*2
+*cancels the i-th polynomial in the standardbase s
+*/
+void deleteInS (int i,kStrategy strat)
+{
+#ifdef ENTER_USE_MEMMOVE
+  memmove(&(strat->S[i]), &(strat->S[i+1]), (strat->sl - i)*sizeof(poly));
+  memmove(&(strat->ecartS[i]),&(strat->ecartS[i+1]),(strat->sl - i)*sizeof(int));
+  memmove(&(strat->sevS[i]),&(strat->sevS[i+1]),(strat->sl - i)*sizeof(long));
+  memmove(&(strat->S_2_R[i]),&(strat->S_2_R[i+1]),(strat->sl - i)*sizeof(int));
+#else
+  int j;
+  for (j=i; j<strat->sl; j++)
+  {
+    strat->S[j] = strat->S[j+1];
+    strat->ecartS[j] = strat->ecartS[j+1];
+    strat->sevS[j] = strat->sevS[j+1];
+    strat->S_2_R[j] = strat->S_2_R[j+1];
+  }
+#endif
+  if (strat->lenS!=NULL)
+  {
+#ifdef ENTER_USE_MEMMOVE
+    memmove(&(strat->lenS[i]),&(strat->lenS[i+1]),(strat->sl - i)*sizeof(int));
+#else
+    for (j=i; j<strat->sl; j++) strat->lenS[j] = strat->lenS[j+1];
+#endif
+  }
+  if (strat->lenSw!=NULL)
+  {
+#ifdef ENTER_USE_MEMMOVE
+    memmove(&(strat->lenSw[i]),&(strat->lenSw[i+1]),(strat->sl - i)*sizeof(int));
+#else
+    for (j=i; j<strat->sl; j++) strat->lenSw[j] = strat->lenSw[j+1];
+#endif
+  }
+  if (strat->fromQ!=NULL)
+  {
+#ifdef ENTER_USE_MEMMOVE
+    memmove(&(strat->fromQ[i]),&(strat->fromQ[i+1]),(strat->sl - i)*sizeof(int));
+#else
+    for (j=i; j<strat->sl; j++)
+    {
+      strat->fromQ[j] = strat->fromQ[j+1];
+    }
+#endif
+  }
+  strat->S[strat->sl] = NULL;
+  strat->sl--;
+}
+
+/*2
+*cancels the j-th polynomial in the set
+*/
+void deleteInL (LSet set, int *length, int j,kStrategy strat)
+{
+  if (set[j].lcm!=NULL)
+    pLmFree(set[j].lcm);
+  if (set[j].p!=NULL)
+  {
+    if (pNext(set[j].p) == strat->tail)
+    {
+      pLmFree(set[j].p);
+      /*- tail belongs to several int spolys -*/
+    }
+    else
+    {
+      // search p in T, if it is there, do not delete it
+      if (pOrdSgn != -1 || kFindInT(set[j].p, strat) < 0)
+      {
+        // assure that for global ordereings kFindInT fails
+        assume(pOrdSgn == -1 || kFindInT(set[j].p, strat) < 0);
+        set[j].Delete();
+      }
+    }
+  }
+  if (*length > 0 && j < *length)
+  {
+#ifdef ENTER_USE_MEMMOVE
+    memmove(&(set[j]), &(set[j+1]), (*length - j)*sizeof(LObject));
+#else
+    int i;
+    for (i=j; i < (*length); i++)
+      set[i] = set[i+1];
+#endif
+  }
+#ifdef KDEBUG
+  memset(&(set[*length]),0,sizeof(LObject));
+#endif
+  (*length)--;
+}
+
+/*2
+*is used after updating the pairset,if the leading term of p
+*divides the leading term of some S[i] it will be canceled
+*/
+static inline void clearS (poly p, unsigned long p_sev, int* at, int* k,
+                    kStrategy strat)
+{
+  assume(p_sev == pGetShortExpVector(p));
+  if (!pLmShortDivisibleBy(p,p_sev, strat->S[*at], ~ strat->sevS[*at])) return;
+  deleteInS((*at),strat);
+  (*at)--;
+  (*k)--;
+}
+
+/*2
+*enters p at position at in L
+*/
+void enterL (LSet *set,int *length, int *LSetmax, LObject p,int at)
+{
+  int i;
+  // this should be corrected
+  assume(p.FDeg == p.pFDeg());
+  if ((*length)>=0)
+  {
+    if ((*length) == (*LSetmax)-1) enlargeL(set,LSetmax,setmaxLinc);
+    if (at <= (*length))
+#ifdef ENTER_USE_MEMMOVE
+      memmove(&((*set)[at+1]), &((*set)[at]), ((*length)-at+1)*sizeof(LObject));
+#else
+    for (i=(*length)+1; i>=at+1; i--) (*set)[i] = (*set)[i-1];
+#endif
+  }
+  else at = 0;
+  (*set)[at] = p;
+  (*length)++;
+}
+
+/*2
+* computes the normal ecart;
+* used in mora case and if pLexOrder & sugar in bba case
+*/
+void initEcartNormal (LObject* h)
+{
+  h->FDeg = h->pFDeg();
+  h->ecart = h->pLDeg() - h->FDeg;
+}
+
+void initEcartBBA (LObject* h)
+{
+  h->FDeg = h->pFDeg();
+  (*h).ecart = 0;
+  (*h).length = 0;
+}
+
+void initEcartPairBba (LObject* Lp,poly f,poly g,int ecartF,int ecartG)
+{
+  Lp->FDeg = Lp->pFDeg();
+  (*Lp).ecart = 0;
+  (*Lp).length = 0;
+}
+
+void initEcartPairMora (LObject* Lp,poly f,poly g,int ecartF,int ecartG)
+{
+  Lp->FDeg = Lp->pFDeg();
+  (*Lp).ecart = si_max(ecartF,ecartG);
+  (*Lp).ecart = (*Lp).ecart- (Lp->FDeg -pFDeg((*Lp).lcm));
+  (*Lp).length = 0;
+}
+
+/*2
+*if ecart1<=ecart2 it returns TRUE
+*/
+BOOLEAN sugarDivisibleBy(int ecart1, int ecart2)
+{
+  return (ecart1 <= ecart2);
+}
+
+/*2
+* put the pair (s[i],p)  into the set B, ecart=ecart(p)
+*/
+void enterOnePair (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
+{
+  assume(i<=strat->sl);
+
+  int      l,j,compare;
+  LObject  Lp;
+
+  if (strat->interred_flag) return;
+#ifdef KDEBUG
+  Lp.ecart=0; Lp.length=0;
+#endif
+  /*- computes the lcm(s[i],p) -*/
+  Lp.lcm = pInit();
+
+  pLcm(p,strat->S[i],Lp.lcm);
+  pSetm(Lp.lcm);
+  if (strat->sugarCrit)
+  {
+    if(
+    (!((strat->ecartS[i]>0)&&(ecart>0)))
+    && pHasNotCF(p,strat->S[i]))
+    {
+    /*
+    *the product criterion has applied for (s,p),
+    *i.e. lcm(s,p)=product of the leading terms of s and p.
+    *Suppose (s,r) is in L and the leading term
+    *of p divides lcm(s,r)
+    *(==> the leading term of p divides the leading term of r)
+    *but the leading term of s does not divide the leading term of r
+    *(notice that tis condition is automatically satisfied if r is still
+    *in S), then (s,r) can be cancelled.
+    *This should be done here because the
+    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
+    *
+    *Moreover, skipping (s,r) holds also for the noncommutative case.
+    */
+      strat->cp++;
+      pLmFree(Lp.lcm);
+      Lp.lcm=NULL;
+      return;
+    }
+    else
+      Lp.ecart = si_max(ecart,strat->ecartS[i]);
+    if (strat->fromT && (strat->ecartS[i]>ecart))
+    {
+      pLmFree(Lp.lcm);
+      Lp.lcm=NULL;
+      return;
+      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
+    }
+    /*
+    *the set B collects the pairs of type (S[j],p)
+    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
+    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
+    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
+    */
+    {
+      j = strat->Bl;
+      loop
+      {
+        if (j < 0)  break;
+        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
+        if ((compare==1)
+        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
+        {
+          strat->c3++;
+          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
+          {
+            pLmFree(Lp.lcm);
+            return;
+          }
+          break;
+        }
+        else
+        if ((compare ==-1)
+        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
+        {
+          deleteInL(strat->B,&strat->Bl,j,strat);
+          strat->c3++;
+        }
+        j--;
+      }
+    }
+  }
+  else /*sugarcrit*/
+  {
+#ifdef HAVE_PLURAL
+    if (!rIsPluralRing(currRing))
+    {
+    // if currRing->nc_type!=quasi (or skew)
+#endif
+
+    if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
+    pHasNotCF(p,strat->S[i]))
+    {
+    /*
+    *the product criterion has applied for (s,p),
+    *i.e. lcm(s,p)=product of the leading terms of s and p.
+    *Suppose (s,r) is in L and the leading term
+    *of p devides lcm(s,r)
+    *(==> the leading term of p devides the leading term of r)
+    *but the leading term of s does not devide the leading term of r
+    *(notice that tis condition is automatically satisfied if r is still
+    *in S), then (s,r) can be canceled.
+    *This should be done here because the
+    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
+    */
+      if (!rIsPluralRing(currRing))
+      {
+        strat->cp++;
+        pLmFree(Lp.lcm);
+        Lp.lcm=NULL;
+        return;
+      }
+    }
+    if (strat->fromT && (strat->ecartS[i]>ecart))
+    {
+      pLmFree(Lp.lcm);
+      Lp.lcm=NULL;
+      return;
+      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
+    }
+    /*
+    *the set B collects the pairs of type (S[j],p)
+    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
+    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
+    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
+    */
+    for(j = strat->Bl;j>=0;j--)
+    {
+      compare=pDivComp(strat->B[j].lcm,Lp.lcm);
+      if (compare==1)
+      {
+        strat->c3++;
+        if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
+        {
+          pLmFree(Lp.lcm);
+          return;
+        }
+        break;
+      }
+      else
+      if (compare ==-1)
+      {
+        deleteInL(strat->B,&strat->Bl,j,strat);
+        strat->c3++;
+      }
+    }
+  }
+#ifdef HAVE_PLURAL
+  }
+#endif
+  /*
+  *the pair (S[i],p) enters B if the spoly != 0
+  */
+  /*-  compute the short s-polynomial -*/
+  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
+    pNorm(p);
+  if ((strat->S[i]==NULL) || (p==NULL))
+    return;
+  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
+    Lp.p=NULL;
+  else
+  {
+#ifdef HAVE_PLURAL
+    if (currRing->nc!=NULL)
+    {
+      if ((currRing->nc->type==nc_lie) && (pHasNotCF(p,strat->S[i])))
+        /* generalized prod-crit for lie-type */
+      {
+          strat->cp++;
+          Lp.p = nc_p_Bracket_qq(pCopy(p),strat->S[i]);
+      }
+      else  Lp.p = nc_spGSpolyCreate(strat->S[i],p,NULL,currRing);
+    }
+    else
+    {
+#endif
+    Lp.p = ksCreateShortSpoly(strat->S[i],p, strat->tailRing);
+#ifdef HAVE_PLURAL
+    }
+#endif
+  }
+  if (Lp.p == NULL)
+  {
+    /*- the case that the s-poly is 0 -*/
+    if (strat->pairtest==NULL) initPairtest(strat);
+    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
+    strat->pairtest[strat->sl+1] = TRUE;
+    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
+    /*
+    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
+    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
+    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
+    *term of p devides the lcm(s,r)
+    *(this canceling should be done here because
+    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
+    *the first case is handeled in chainCrit
+    */
+    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
+  }
+  else
+  {
+    /*- the pair (S[i],p) enters B -*/
+    Lp.p1 = strat->S[i];
+    Lp.p2 = p;
+
+#ifdef HAVE_PLURAL
+    if (currRing->nc==NULL)
+    {
+#endif
+
+     pNext(Lp.p) = strat->tail;
+
+#ifdef HAVE_PLURAL
+    }
+#endif
+
+    if (atR >= 0)
+    {
+      Lp.i_r2 = atR;
+      Lp.i_r1 = strat->S_2_R[i];
+    }
+    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
+    if (TEST_OPT_INTSTRATEGY)
+    {
+
+#ifdef HAVE_PLURAL
+      if (currRing->nc==NULL)
+      {
+#endif
+
+      nDelete(&(Lp.p->coef));
+
+#ifdef HAVE_PLURAL
+      }
+#endif
+
+    }
+    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
+    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
+  }
+}
+
+/*2
+* put the pair (s[i],p) into the set L, ecart=ecart(p)
+* in the case that s forms a SB of (s)
+*/
+void enterOnePairSpecial (int i,poly p,int ecart,kStrategy strat, int atR = -1)
+{
+  //PrintS("try ");wrp(strat->S[i]);PrintS(" and ");wrp(p);PrintLn();
+  if(pHasNotCF(p,strat->S[i]))
+  {
+    //PrintS("prod-crit\n");
+      if (!rIsPluralRing(currRing))
+      {
+        strat->cp++;
+        return;
+      }
+  }
+
+  int      l,j,compare;
+  LObject  Lp;
+
+  Lp.lcm = pInit();
+  pLcm(p,strat->S[i],Lp.lcm);
+  pSetm(Lp.lcm);
+  for(j = strat->Ll;j>=0;j--)
+  {
+    compare=pDivComp(strat->L[j].lcm,Lp.lcm);
+    if ((compare==1) || (pLmEqual(strat->L[j].lcm,Lp.lcm)))
+    {
+      //PrintS("c3-crit\n");
+      strat->c3++;
+      pLmFree(Lp.lcm);
+      return;
+    }
+    else if (compare ==-1)
+    {
+      //Print("c3-crit with L[%d]\n",j);
+      deleteInL(strat->L,&strat->Ll,j,strat);
+      strat->c3++;
+    }
+  }
+  /*-  compute the short s-polynomial -*/
+
+  Lp.p = ksCreateShortSpoly(strat->S[i],p,strat->tailRing);
+  if (Lp.p == NULL)
+  {
+     pLmFree(Lp.lcm);
+  }
+  else
+  {
+    /*- the pair (S[i],p) enters L -*/
+    Lp.p1 = strat->S[i];
+    Lp.p2 = p;
+    if (atR >= 0)
+    {
+      Lp.i_r1 = strat->S_2_R[i];
+      Lp.i_r2 = atR;
+    }
+    pNext(Lp.p) = strat->tail;
+    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
+    if (TEST_OPT_INTSTRATEGY)
+    {
+      nDelete(&(Lp.p->coef));
+    }
+    l = strat->posInL(strat->L,strat->Ll,&Lp,strat);
+    //Print("-> L[%d]\n",l);
+    enterL(&strat->L,&strat->Ll,&strat->Lmax,Lp,l);
+  }
+}
+
+/*2
+*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
+*using the chain-criterion in B and L and enters B to L
+*/
+void chainCrit (poly p,int ecart,kStrategy strat)
+{
+  int i,j,l;
+
+  /*
+  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
+  *In this case all elements in B such
+  *that their lcm is divisible by the leading term of S[i] can be canceled
+  */
+  if (strat->pairtest!=NULL)
+  {
+    {
+      /*- i.e. there is an i with pairtest[i]==TRUE -*/
+      for (j=0; j<=strat->sl; j++)
+      {
+        if (strat->pairtest[j])
+        {
+          for (i=strat->Bl; i>=0; i--)
+          {
+            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
+            {
+              deleteInL(strat->B,&strat->Bl,i,strat);
+              strat->c3++;
+            }
+          }
+        }
+      }
+    }
+    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
+    strat->pairtest=NULL;
+  }
+  if (strat->Gebauer || strat->fromT)
+  {
+    if (strat->sugarCrit)
+    {
+    /*
+    *suppose L[j] == (s,r) and p/lcm(s,r)
+    *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
+    *and in case the sugar is o.k. then L[j] can be canceled
+    */
+      for (j=strat->Ll; j>=0; j--)
+      {
+        if (sugarDivisibleBy(ecart,strat->L[j].ecart)
+        && ((pNext(strat->L[j].p) == strat->tail) || (pOrdSgn==1))
+        && pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
+        {
+          if (strat->L[j].p == strat->tail)
+          {
+            deleteInL(strat->L,&strat->Ll,j,strat);
+            strat->c3++;
+          }
+        }
+      }
+      /*
+      *this is GEBAUER-MOELLER:
+      *in B all elements with the same lcm except the "best"
+      *(i.e. the last one in B with this property) will be canceled
+      */
+      j = strat->Bl;
+      loop /*cannot be changed into a for !!! */
+      {
+        if (j <= 0) break;
+        i = j-1;
+        loop
+        {
+          if (i <  0) break;
+          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
+          {
+            strat->c3++;
+            if (sugarDivisibleBy(strat->B[j].ecart,strat->B[i].ecart))
+            {
+              deleteInL(strat->B,&strat->Bl,i,strat);
+              j--;
+            }
+            else
+            {
+              deleteInL(strat->B,&strat->Bl,j,strat);
+              break;
+            }
+          }
+          i--;
+        }
+        j--;
+      }
+    }
+    else /*sugarCrit*/
+    {
+      /*
+      *suppose L[j] == (s,r) and p/lcm(s,r)
+      *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
+      *and in case the sugar is o.k. then L[j] can be canceled
+      */
+      for (j=strat->Ll; j>=0; j--)
+      {
+        if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
+        {
+          if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
+          {
+            deleteInL(strat->L,&strat->Ll,j,strat);
+            strat->c3++;
+          }
+        }
+      }
+      /*
+      *this is GEBAUER-MOELLER:
+      *in B all elements with the same lcm except the "best"
+      *(i.e. the last one in B with this property) will be canceled
+      */
+      j = strat->Bl;
+      loop   /*cannot be changed into a for !!! */
+      {
+        if (j <= 0) break;
+        for(i=j-1; i>=0; i--)
+        {
+          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
+          {
+            strat->c3++;
+            deleteInL(strat->B,&strat->Bl,i,strat);
+            j--;
+          }
+        }
+        j--;
+      }
+    }
+    /*
+    *the elements of B enter L/their order with respect to B is kept
+    *j = posInL(L,j,B[i]) would permutate the order
+    *if once B is ordered different from L
+    *then one should use j = posInL(L,Ll,B[i])
+    */
+    j = strat->Ll+1;
+    for (i=strat->Bl; i>=0; i--)
+    {
+      j = strat->posInL(strat->L,j-1,&(strat->B[i]),strat);
+      enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
+    }
+    strat->Bl = -1;
+  }
+  else
+  {
+    for (j=strat->Ll; j>=0; j--)
+    {
+      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
+      {
+        if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
+        {
+          deleteInL(strat->L,&strat->Ll,j,strat);
+          strat->c3++;
+        }
+      }
+    }
+    /*
+    *this is our MODIFICATION of GEBAUER-MOELLER:
+    *First the elements of B enter L,
+    *then we fix a lcm and the "best" element in L
+    *(i.e the last in L with this lcm and of type (s,p))
+    *and cancel all the other elements of type (r,p) with this lcm
+    *except the case the element (s,r) has also the same lcm
+    *and is on the worst position with respect to (s,p) and (r,p)
+    */
+    /*
+    *B enters to L/their order with respect to B is permutated for elements
+    *B[i].p with the same leading term
+    */
+    j = strat->Ll;
+    for (i=strat->Bl; i>=0; i--)
+    {
+      j = strat->posInL(strat->L,j,&(strat->B[i]),strat);
+      enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
+    }
+    strat->Bl = -1;
+    j = strat->Ll;
+    loop  /*cannot be changed into a for !!! */
+    {
+      if (j <= 0)
+      {
+        /*now L[0] cannot be canceled any more and the tail can be removed*/
+        if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
+        break;
+      }
+      if (strat->L[j].p2 == p)
+      {
+        i = j-1;
+        loop
+        {
+          if (i < 0)  break;
+          if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
+          {
+            /*L[i] could be canceled but we search for a better one to cancel*/
+            strat->c3++;
+            if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
+            && (pNext(strat->L[l].p) == strat->tail)
+            && (!pLmEqual(strat->L[i].p,strat->L[l].p))
+            && pDivisibleBy(p,strat->L[l].lcm))
+            {
+              /*
+              *"NOT equal(...)" because in case of "equal" the element L[l]
+              *is "older" and has to be from theoretical point of view behind
+              *L[i], but we do not want to reorder L
+              */
+              strat->L[i].p2 = strat->tail;
+              /*
+              *L[l] will be canceled, we cannot cancel L[i] later on,
+              *so we mark it with "tail"
+              */
+              deleteInL(strat->L,&strat->Ll,l,strat);
+              i--;
+            }
+            else
+            {
+              deleteInL(strat->L,&strat->Ll,i,strat);
+            }
+            j--;
+          }
+          i--;
+        }
+      }
+      else if (strat->L[j].p2 == strat->tail)
+      {
+        /*now L[j] cannot be canceled any more and the tail can be removed*/
+        strat->L[j].p2 = p;
+      }
+      j--;
+    }
+  }
+}
+
+/*2
+*(s[0],h),...,(s[k],h) will be put to the pairset L
+*/
+void initenterpairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
+{
+
+  if ((strat->syzComp==0)
+  || (pGetComp(h)<=strat->syzComp))
+  {
+    int j;
+    BOOLEAN new_pair=FALSE;
+
+    if (pGetComp(h)==0)
+    {
+      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
+      if ((isFromQ)&&(strat->fromQ!=NULL))
+      {
+        for (j=0; j<=k; j++)
+        {
+          if (!strat->fromQ[j])
+          {
+            new_pair=TRUE;
+            enterOnePair(j,h,ecart,isFromQ,strat, atR);
+          //Print("j:%d, Ll:%d\n",j,strat->Ll);
+          }
+        }
+      }
+      else
+      {
+        new_pair=TRUE;
+        for (j=0; j<=k; j++)
+        {
+          enterOnePair(j,h,ecart,isFromQ,strat, atR);
+          //Print("j:%d, Ll:%d\n",j,strat->Ll);
+        }
+      }
+    }
+    else
+    {
+      for (j=0; j<=k; j++)
+      {
+        if ((pGetComp(h)==pGetComp(strat->S[j]))
+        || (pGetComp(strat->S[j])==0))
+        {
+          new_pair=TRUE;
+          enterOnePair(j,h,ecart,isFromQ,strat, atR);
+        //Print("j:%d, Ll:%d\n",j,strat->Ll);
+        }
+      }
+    }
+
+    if (new_pair) chainCrit(h,ecart,strat);
+
+  }
+}
+
+/*2
+*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
+*superfluous elements in S will be deleted
+*/
+void enterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
+{
+  int j=pos;
+
+  initenterpairs(h,k,ecart,0,strat, atR);
+  if ( (!strat->fromT)
+  && ((strat->syzComp==0)
+    ||(pGetComp(h)<=strat->syzComp)))
+  {
+    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
+    unsigned long h_sev = pGetShortExpVector(h);
+    loop
+    {
+      if (j > k) break;
+      clearS(h,h_sev, &j,&k,strat);
+      j++;
+    }
+    //Print("end clearS sl=%d\n",strat->sl);
+  }
+ // PrintS("end enterpairs\n");
+}
+
+/*2
+*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
+*superfluous elements in S will be deleted
+*/
+void enterpairsSpecial (poly h,int k,int ecart,int pos,kStrategy strat, int atR = -1)
+{
+  int j;
+
+  for (j=0; j<=k; j++)
+  {
+    if ((pGetComp(h)==pGetComp(strat->S[j]))
+    || (0==pGetComp(strat->S[j])))
+    {
+      enterOnePairSpecial(j,h,ecart,strat, atR);
+    }
+  }
+  j=pos;
+  loop
+  {
+    unsigned long h_sev = pGetShortExpVector(h);
+    if (j > k) break;
+    clearS(h,h_sev,&j,&k,strat);
+    j++;
+  }
+}
+
+/*2
+*constructs the pairset at the beginning
+*of the buchberger/mora algorithm
+*/
+void pairs (kStrategy strat)
+{
+  int j,i;
+//  Print("pairs:sl=%d\n",strat->sl);
+//  for (i=0; i<=strat->sl; i++)
+//  {
+//    Print("s%d:",i);pWrite(strat->S[i]);
+//  }
+  if (strat->fromQ!=NULL)
+  {
+    for (i=1; i<=strat->sl; i++)
+    {
+      initenterpairs(strat->S[i],i-1,strat->ecartS[i],strat->fromQ[i],strat);
+    }
+  }
+  else
+  {
+    for (i=1; i<=strat->sl; i++)
+    {
+      initenterpairs(strat->S[i],i-1,strat->ecartS[i],0,strat);
+    }
+  }
+  /*deletes superfluous elements in S*/
+  i = -1;
+  loop
+  {
+    i++;
+    if (i >= strat->sl) break;
+    if ((strat->syzComp==0) || (pGetComp(strat->S[i])<=strat->syzComp))
+    {
+      j=i;
+      loop
+      {
+        j++;
+        if (j > strat->sl) break;
+        if (pLmShortDivisibleBy(strat->S[i], strat->sevS[i],
+                              strat->S[j], ~ strat->sevS[j]))
+        {
+        //  Print("delete %d=",j);
+        //  wrp(strat->S[j]);
+        //  Print(" wegen %d=",i);
+        //  wrp(strat->S[i]);
+        //  Print("( fromQ=%d)\n", (strat->fromQ) ? strat->fromQ[j]:0);
+          if ((strat->fromQ==NULL) || (strat->fromQ[j]==0))
+          {
+            deleteInS(j,strat);
+            j--;
+          }
+        }
+      }
+    }
+  }
+}
+
+/*2
+*reorders  s with respect to posInS,
+*suc is the first changed index or zero
+*/
+void reorderS (int* suc,kStrategy strat)
+{
+  int i,j,at,ecart, s2r;
+  int fq=0;
+  unsigned long sev;
+  poly  p;
+
+  *suc = -1;
+  for (i=1; i<=strat->sl; i++)
+  {
+    at = posInS(strat,i-1,strat->S[i],strat->ecartS[i]);
+    if (at != i)
+    {
+      if ((*suc > at) || (*suc == -1)) *suc = at;
+      p = strat->S[i];
+      ecart = strat->ecartS[i];
+      sev = strat->sevS[i];
+      s2r = strat->S_2_R[i];
+      if (strat->fromQ!=NULL) fq=strat->fromQ[i];
+      for (j=i; j>=at+1; j--)
+      {
+        strat->S[j] = strat->S[j-1];
+        strat->ecartS[j] = strat->ecartS[j-1];
+        strat->sevS[j] = strat->sevS[j-1];
+        strat->S_2_R[j] = strat->S_2_R[j-1];
+      }
+      strat->S[at] = p;
+      strat->ecartS[at] = ecart;
+      strat->sevS[at] = sev;
+      strat->S_2_R[at] = s2r;
+      if (strat->fromQ!=NULL)
+      {
+        for (j=i; j>=at+1; j--)
+        {
+          strat->fromQ[j] = strat->fromQ[j-1];
+        }
+        strat->fromQ[at]=fq;
+      }
+    }
+  }
+}
+
+
+/*2
+*looks up the position of p in set
+*set[0] is the smallest with respect to the ordering-procedure
+*pComp
+* Assumption: posInS only depends on the leading term
+*             otherwise, bba has to be changed
+*/
+int posInS (kStrategy strat, int length,poly p, int ecart_p)
+{
+  if(length==-1) return 0;
+  polyset set=strat->S;
+  int i;
+  int an = 0;
+  int en= length;
+  int cmp_int=pOrdSgn;
+  if (currRing->MixedOrder)
+  {
+    int o=pWTotaldegree(p);
+    int oo=pWTotaldegree(set[length]);
+
+    if ((oo<o)
+    || ((o==oo) && (pLmCmp(set[length],p)!= cmp_int)))
+      return length+1;
+
+    loop
+    {
+      if (an >= en-1)
+      {
+        if ((pWTotaldegree(set[an])>=o) && (pLmCmp(set[an],p) == cmp_int))
+        {
+          return an;
+        }
+        return en;
+      }
+      i=(an+en) / 2;
+      if ((pWTotaldegree(set[an])>=o)
+      && (pLmCmp(set[i],p) == cmp_int)) en=i;
+      else                              an=i;
+    }
+  }
+  else
+  {
+    if (pLmCmp(set[length],p)== -cmp_int)
+      return length+1;
+
+    loop
+    {
+      if (an >= en-1)
+      {
+        if (pLmCmp(set[an],p) == cmp_int) return an;
+        if (pLmCmp(set[an],p) == -cmp_int) return en;
+        if ((cmp_int!=1)
+        && ((strat->ecartS[an])>ecart_p))
+          return an;
+        return en;
+      }
+      i=(an+en) / 2;
+      if (pLmCmp(set[i],p) == cmp_int) en=i;
+      else if (pLmCmp(set[i],p) == -cmp_int) an=i;
+      else
+      {
+        if ((cmp_int!=1)
+        &&((strat->ecartS[i])<ecart_p))
+          en=i;
+        else
+          an=i;
+      }
+    }
+  }
+}
+
+
+/*2
+* looks up the position of p in set
+* the position is the last one
+*/
+int posInT0 (const TSet set,const int length,LObject &p)
+{
+  return (length+1);
+}
+
+
+/*2
+* looks up the position of p in T
+* set[0] is the smallest with respect to the ordering-procedure
+* pComp
+*/
+int posInT1 (const TSet set,const int length,LObject &p)
+{
+  if (length==-1) return 0;
+
+  if (pLmCmp(set[length].p,p.p)!= pOrdSgn) return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (pLmCmp(set[an].p,p.p) == pOrdSgn) return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    if (pLmCmp(set[i].p,p.p) == pOrdSgn) en=i;
+    else                                 an=i;
+  }
+}
+
+/*2
+* looks up the position of p in T
+* set[0] is the smallest with respect to the ordering-procedure
+* length
+*/
+int posInT2 (const TSet set,const int length,LObject &p)
+{
+  if (length==-1)
+    return 0;
+  if (set[length].length<p.length)
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (set[an].length>p.length) return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    if (set[i].length>p.length) en=i;
+    else                        an=i;
+  }
+}
+
+/*2
+* looks up the position of p in T
+* set[0] is the smallest with respect to the ordering-procedure
+* totaldegree,pComp
+*/
+int posInT11 (const TSet set,const int length,LObject &p)
+/*{
+ * int j=0;
+ * int o;
+ *
+ * o = p.GetpFDeg();
+ * loop
+ * {
+ *   if ((pFDeg(set[j].p) > o)
+ *   || ((pFDeg(set[j].p) == o) && (pLmCmp(set[j].p,p.p) == pOrdSgn)))
+ *   {
+ *     return j;
+ *   }
+ *   j++;
+ *   if (j > length) return j;
+ * }
+ *}
+ */
+{
+  if (length==-1) return 0;
+
+  int o = p.GetpFDeg();
+  int op = set[length].GetpFDeg();
+
+  if ((op < o)
+  || ((op == o) && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+
+  loop
+  {
+    if (an >= en-1)
+    {
+      op= set[an].GetpFDeg();
+      if ((op > o)
+      || (( op == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
+        return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    op = set[i].GetpFDeg();
+    if (( op > o)
+    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
+      en=i;
+    else
+      an=i;
+  }
+}
+
+/*2
+* looks up the position of p in T
+* set[0] is the smallest with respect to the ordering-procedure
+* totaldegree,pComp
+*/
+int posInT110 (const TSet set,const int length,LObject &p)
+{
+  if (length==-1) return 0;
+
+  int o = p.GetpFDeg();
+  int op = set[length].GetpFDeg();
+
+  if (( op < o)
+  || (( op == o) && (set[length].length<p.length))
+  || (( op == o) && (set[length].length == p.length)
+     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      op = set[an].GetpFDeg();
+      if (( op > o)
+      || (( op == o) && (set[an].length > p.length))
+      || (( op == o) && (set[an].length == p.length)
+         && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
+        return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    op = set[i].GetpFDeg();
+    if (( op > o)
+    || (( op == o) && (set[i].length > p.length))
+    || (( op == o) && (set[i].length == p.length)
+       && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
+      en=i;
+    else
+      an=i;
+  }
+}
+
+/*2
+* looks up the position of p in set
+* set[0] is the smallest with respect to the ordering-procedure
+* pFDeg
+*/
+int posInT13 (const TSet set,const int length,LObject &p)
+{
+  if (length==-1) return 0;
+
+  int o = p.GetpFDeg();
+
+  if (set[length].GetpFDeg() <= o)
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (set[an].GetpFDeg() > o)
+        return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    if (set[i].GetpFDeg() > o)
+      en=i;
+    else
+      an=i;
+  }
+}
+
+// determines the position based on: 1.) Ecart 2.) pLength
+int posInT_EcartpLength(const TSet set,const int length,LObject &p)
+{
+  if (length==-1) return 0;
+
+  int op=p.ecart;
+  int ol = p.GetpLength();
+
+  int oo=set[length].ecart;
+  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+    {
+      if (an >= en-1)
+      {
+        int oo=set[an].ecart;
+        if((oo > op)
+           || ((oo==op) && (set[an].pLength > ol)))
+          return an;
+        return en;
+      }
+      i=(an+en) / 2;
+      int oo=set[i].ecart;
+      if ((oo > op)
+          || ((oo == op) && (set[i].pLength > ol)))
+        en=i;
+      else
+        an=i;
+    }
+}
+
+/*2
+* looks up the position of p in set
+* set[0] is the smallest with respect to the ordering-procedure
+* maximaldegree, pComp
+*/
+int posInT15 (const TSet set,const int length,LObject &p)
+/*{
+ *int j=0;
+ * int o;
+ *
+ * o = p.GetpFDeg()+p.ecart;
+ * loop
+ * {
+ *   if ((set[j].GetpFDeg()+set[j].ecart > o)
+ *   || ((set[j].GetpFDeg()+set[j].ecart == o)
+ *     && (pLmCmp(set[j].p,p.p) == pOrdSgn)))
+ *   {
+ *     return j;
+ *   }
+ *   j++;
+ *   if (j > length) return j;
+ * }
+ *}
+ */
+{
+  if (length==-1) return 0;
+
+  int o = p.GetpFDeg() + p.ecart;
+  int op = set[length].GetpFDeg()+set[length].ecart;
+
+  if ((op < o)
+  || ((op == o)
+     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      op = set[an].GetpFDeg()+set[an].ecart;
+      if (( op > o)
+      || (( op  == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
+        return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    op = set[i].GetpFDeg()+set[i].ecart;
+    if (( op > o)
+    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
+      en=i;
+    else
+      an=i;
+  }
+}
+
+/*2
+* looks up the position of p in set
+* set[0] is the smallest with respect to the ordering-procedure
+* pFDeg+ecart, ecart, pComp
+*/
+int posInT17 (const TSet set,const int length,LObject &p)
+/*
+*{
+* int j=0;
+* int  o;
+*
+*  o = p.GetpFDeg()+p.ecart;
+*  loop
+*  {
+*    if ((pFDeg(set[j].p)+set[j].ecart > o)
+*    || (((pFDeg(set[j].p)+set[j].ecart == o)
+*      && (set[j].ecart < p.ecart)))
+*    || ((pFDeg(set[j].p)+set[j].ecart == o)
+*      && (set[j].ecart==p.ecart)
+*      && (pLmCmp(set[j].p,p.p)==pOrdSgn)))
+*      return j;
+*    j++;
+*    if (j > length) return j;
+*  }
+* }
+*/
+{
+  if (length==-1) return 0;
+
+  int o = p.GetpFDeg() + p.ecart;
+  int op = set[length].GetpFDeg()+set[length].ecart;
+
+  if ((op < o)
+  || (( op == o) && (set[length].ecart > p.ecart))
+  || (( op == o) && (set[length].ecart==p.ecart)
+     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      op = set[an].GetpFDeg()+set[an].ecart;
+      if (( op > o)
+      || (( op == o) && (set[an].ecart < p.ecart))
+      || (( op  == o) && (set[an].ecart==p.ecart)
+         && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
+        return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    op = set[i].GetpFDeg()+set[i].ecart;
+    if ((op > o)
+    || (( op == o) && (set[i].ecart < p.ecart))
+    || (( op == o) && (set[i].ecart == p.ecart)
+       && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
+      en=i;
+    else
+      an=i;
+  }
+}
+/*2
+* looks up the position of p in set
+* set[0] is the smallest with respect to the ordering-procedure
+* pGetComp, pFDeg+ecart, ecart, pComp
+*/
+int posInT17_c (const TSet set,const int length,LObject &p)
+{
+  if (length==-1) return 0;
+
+  int cc = (-1+2*currRing->order[0]==ringorder_c);
+  /* cc==1 for (c,..), cc==-1 for (C,..) */
+  int o = p.GetpFDeg() + p.ecart;
+  int c = pGetComp(p.p)*cc;
+
+  if (pGetComp(set[length].p)*cc < c)
+    return length+1;
+  if (pGetComp(set[length].p)*cc == c)
+  {
+    int op = set[length].GetpFDeg()+set[length].ecart;
+    if ((op < o)
+    || ((op == o) && (set[length].ecart > p.ecart))
+    || ((op == o) && (set[length].ecart==p.ecart)
+       && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
+      return length+1;
+  }
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (pGetComp(set[an].p)*cc < c)
+        return en;
+      if (pGetComp(set[an].p)*cc == c)
+      {
+        int op = set[an].GetpFDeg()+set[an].ecart;
+        if ((op > o)
+        || ((op == o) && (set[an].ecart < p.ecart))
+        || ((op == o) && (set[an].ecart==p.ecart)
+           && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
+          return an;
+      }
+      return en;
+    }
+    i=(an+en) / 2;
+    if (pGetComp(set[i].p)*cc > c)
+      en=i;
+    else if (pGetComp(set[i].p)*cc == c)
+    {
+      int op = set[i].GetpFDeg()+set[i].ecart;
+      if ((op > o)
+      || ((op == o) && (set[i].ecart < p.ecart))
+      || ((op == o) && (set[i].ecart == p.ecart)
+         && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
+        en=i;
+      else
+        an=i;
+    }
+    else
+      an=i;
+  }
+}
+
+/*2
+* looks up the position of p in set
+* set[0] is the smallest with respect to
+* ecart, pFDeg, length
+*/
+int posInT19 (const TSet set,const int length,LObject &p)
+{
+  if (length==-1) return 0;
+
+  int o = p.ecart;
+  int op=p.GetpFDeg();
+
+  if (set[length].ecart < o)
+    return length+1;
+  if (set[length].ecart == o)
+  {
+     int oo=set[length].GetpFDeg();
+     if ((oo < op) || ((oo==op) && (set[length].length < p.length)))
+       return length+1;
+  }
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (set[an].ecart > o)
+        return an;
+      if (set[an].ecart == o)
+      {
+         int oo=set[an].GetpFDeg();
+         if((oo > op)
+         || ((oo==op) && (set[an].length > p.length)))
+           return an;
+      }
+      return en;
+    }
+    i=(an+en) / 2;
+    if (set[i].ecart > o)
+      en=i;
+    else if (set[i].ecart == o)
+    {
+       int oo=set[i].GetpFDeg();
+       if ((oo > op)
+       || ((oo == op) && (set[i].length > p.length)))
+         en=i;
+       else
+        an=i;
+    }
+    else
+      an=i;
+  }
+}
+
+/*2
+*looks up the position of polynomial p in set
+*set[length] is the smallest element in set with respect
+*to the ordering-procedure pComp
+*/
+int posInLSpecial (const LSet set, const int length,
+                   LObject *p,const kStrategy strat)
+{
+  if (length<0) return 0;
+
+  int d=p->GetpFDeg();
+  int op=set[length].GetpFDeg();
+
+  if ((op > d)
+  || ((op == d) && (p->p1!=NULL)&&(set[length].p1==NULL))
+  || (pLmCmp(set[length].p,p->p)== pOrdSgn))
+     return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      op=set[an].GetpFDeg();
+      if ((op > d)
+      || ((op == d) && (p->p1!=NULL) && (set[an].p1==NULL))
+      || (pLmCmp(set[an].p,p->p)== pOrdSgn))
+         return en;
+      return an;
+    }
+    i=(an+en) / 2;
+    op=set[i].GetpFDeg();
+    if ((op>d)
+    || ((op==d) && (p->p1!=NULL) && (set[i].p1==NULL))
+    || (pLmCmp(set[i].p,p->p) == pOrdSgn))
+      an=i;
+    else
+      en=i;
+  }
+}
+
+/*2
+*looks up the position of polynomial p in set
+*set[length] is the smallest element in set with respect
+*to the ordering-procedure pComp
+*/
+int posInL0 (const LSet set, const int length,
+             LObject* p,const kStrategy strat)
+{
+  if (length<0) return 0;
+
+  if (pLmCmp(set[length].p,p->p)== pOrdSgn)
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (pLmCmp(set[an].p,p->p) == pOrdSgn) return en;
+      return an;
+    }
+    i=(an+en) / 2;
+    if (pLmCmp(set[i].p,p->p) == pOrdSgn) an=i;
+    else                                 en=i;
+    /*aend. fuer lazy == in !=- machen */
+  }
+}
+
+/*2
+* looks up the position of polynomial p in set
+* e is the ecart of p
+* set[length] is the smallest element in set with respect
+* to the ordering-procedure totaldegree,pComp
+*/
+int posInL11 (const LSet set, const int length,
+              LObject* p,const kStrategy strat)
+/*{
+ * int j=0;
+ * int o;
+ *
+ * o = p->GetpFDeg();
+ * loop
+ * {
+ *   if (j > length)            return j;
+ *   if ((set[j].GetpFDeg() < o)) return j;
+ *   if ((set[j].GetpFDeg() == o) && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
+ *   {
+ *     return j;
+ *   }
+ *   j++;
+ * }
+ *}
+ */
+{
+  if (length<0) return 0;
+
+  int o = p->GetpFDeg();
+  int op = set[length].GetpFDeg();
+
+  if ((op > o)
+  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
+    return length+1;
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      op = set[an].GetpFDeg();
+      if ((op > o)
+      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
+        return en;
+      return an;
+    }
+    i=(an+en) / 2;
+    op = set[i].GetpFDeg();
+    if ((op > o)
+    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
+      an=i;
+    else
+      en=i;
+  }
+}
+
+/*2
+* looks up the position of polynomial p in set
+* set[length] is the smallest element in set with respect
+* to the ordering-procedure totaldegree,pLength0
+*/
+int posInL110 (const LSet set, const int length,
+               LObject* p,const kStrategy strat)
+{
+  if (length<0) return 0;
+
+  int o = p->GetpFDeg();
+  int op = set[length].GetpFDeg();
+
+  if ((op > o)
+  || ((op == o) && (set[length].length >2*p->length))
+  || ((op == o) && (set[length].length <= 2*p->length)
+     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
+    return length+1;
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      op = set[an].GetpFDeg();
+      if ((op > o)
+      || ((op == o) && (set[an].length >2*p->length))
+      || ((op == o) && (set[an].length <=2*p->length)
+         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
+        return en;
+      return an;
+    }
+    i=(an+en) / 2;
+    op = set[i].GetpFDeg();
+    if ((op > o)
+    || ((op == o) && (set[i].length > 2*p->length))
+    || ((op == o) && (set[i].length <= 2*p->length)
+       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
+      an=i;
+    else
+      en=i;
+  }
+}
+
+/*2
+* looks up the position of polynomial p in set
+* e is the ecart of p
+* set[length] is the smallest element in set with respect
+* to the ordering-procedure totaldegree
+*/
+int posInL13 (const LSet set, const int length,
+              LObject* p,const kStrategy strat)
+{
+  if (length<0) return 0;
+
+  int o = p->GetpFDeg();
+
+  if (set[length].GetpFDeg() > o)
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (set[an].GetpFDeg() >= o)
+        return en;
+      return an;
+    }
+    i=(an+en) / 2;
+    if (set[i].GetpFDeg() >= o)
+      an=i;
+    else
+      en=i;
+  }
+}
+
+/*2
+* looks up the position of polynomial p in set
+* e is the ecart of p
+* set[length] is the smallest element in set with respect
+* to the ordering-procedure maximaldegree,pComp
+*/
+int posInL15 (const LSet set, const int length,
+              LObject* p,const kStrategy strat)
+/*{
+ * int j=0;
+ * int o;
+ *
+ * o = p->ecart+p->GetpFDeg();
+ * loop
+ * {
+ *   if (j > length)                       return j;
+ *   if (set[j].GetpFDeg()+set[j].ecart < o) return j;
+ *   if ((set[j].GetpFDeg()+set[j].ecart == o)
+ *   && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
+ *   {
+ *     return j;
+ *   }
+ *   j++;
+ * }
+ *}
+ */
+{
+  if (length<0) return 0;
+
+  int o = p->GetpFDeg() + p->ecart;
+  int op = set[length].GetpFDeg() + set[length].ecart;
+
+  if ((op > o)
+  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
+    return length+1;
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      op = set[an].GetpFDeg() + set[an].ecart;
+      if ((op > o)
+      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
+        return en;
+      return an;
+    }
+    i=(an+en) / 2;
+    op = set[i].GetpFDeg() + set[i].ecart;
+    if ((op > o)
+    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
+      an=i;
+    else
+      en=i;
+  }
+}
+
+/*2
+* looks up the position of polynomial p in set
+* e is the ecart of p
+* set[length] is the smallest element in set with respect
+* to the ordering-procedure totaldegree
+*/
+int posInL17 (const LSet set, const int length,
+              LObject* p,const kStrategy strat)
+{
+  if (length<0) return 0;
+
+  int o = p->GetpFDeg() + p->ecart;
+
+  if ((set[length].GetpFDeg() + set[length].ecart > o)
+  || ((set[length].GetpFDeg() + set[length].ecart == o)
+     && (set[length].ecart > p->ecart))
+  || ((set[length].GetpFDeg() + set[length].ecart == o)
+     && (set[length].ecart == p->ecart)
+     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
+    return length+1;
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      if ((set[an].GetpFDeg() + set[an].ecart > o)
+      || ((set[an].GetpFDeg() + set[an].ecart == o)
+         && (set[an].ecart > p->ecart))
+      || ((set[an].GetpFDeg() + set[an].ecart == o)
+         && (set[an].ecart == p->ecart)
+         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
+        return en;
+      return an;
+    }
+    i=(an+en) / 2;
+    if ((set[i].GetpFDeg() + set[i].ecart > o)
+    || ((set[i].GetpFDeg() + set[i].ecart == o)
+       && (set[i].ecart > p->ecart))
+    || ((set[i].GetpFDeg() +set[i].ecart == o)
+       && (set[i].ecart == p->ecart)
+       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
+      an=i;
+    else
+      en=i;
+  }
+}
+/*2
+* looks up the position of polynomial p in set
+* e is the ecart of p
+* set[length] is the smallest element in set with respect
+* to the ordering-procedure pComp
+*/
+int posInL17_c (const LSet set, const int length,
+                LObject* p,const kStrategy strat)
+{
+  if (length<0) return 0;
+
+  int cc = (-1+2*currRing->order[0]==ringorder_c);
+  /* cc==1 for (c,..), cc==-1 for (C,..) */
+  int c = pGetComp(p->p)*cc;
+  int o = p->GetpFDeg() + p->ecart;
+
+  if (pGetComp(set[length].p)*cc > c)
+    return length+1;
+  if (pGetComp(set[length].p)*cc == c)
+  {
+    if ((set[length].GetpFDeg() + set[length].ecart > o)
+    || ((set[length].GetpFDeg() + set[length].ecart == o)
+       && (set[length].ecart > p->ecart))
+    || ((set[length].GetpFDeg() + set[length].ecart == o)
+       && (set[length].ecart == p->ecart)
+       && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
+      return length+1;
+  }
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (pGetComp(set[an].p)*cc > c)
+        return en;
+      if (pGetComp(set[an].p)*cc == c)
+      {
+        if ((set[an].GetpFDeg() + set[an].ecart > o)
+        || ((set[an].GetpFDeg() + set[an].ecart == o)
+           && (set[an].ecart > p->ecart))
+        || ((set[an].GetpFDeg() + set[an].ecart == o)
+           && (set[an].ecart == p->ecart)
+           && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
+          return en;
+      }
+      return an;
+    }
+    i=(an+en) / 2;
+    if (pGetComp(set[i].p)*cc > c)
+      an=i;
+    else if (pGetComp(set[i].p)*cc == c)
+    {
+      if ((set[i].GetpFDeg() + set[i].ecart > o)
+      || ((set[i].GetpFDeg() + set[i].ecart == o)
+         && (set[i].ecart > p->ecart))
+      || ((set[i].GetpFDeg() +set[i].ecart == o)
+         && (set[i].ecart == p->ecart)
+         && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
+        an=i;
+      else
+        en=i;
+    }
+    else
+      en=i;
+  }
+}
+
+/***************************************************************
+ *
+ * Tail reductions
+ *
+ ***************************************************************/
+TObject*
+kFindDivisibleByInS(kStrategy strat, int pos, LObject* L, TObject *T,
+                    long ecart)
+{
+  int j = 0;
+  const unsigned long not_sev = ~L->sev;
+  const unsigned long* sev = strat->sevS;
+  poly p;
+  ring r;
+  L->GetLm(p, r);
+
+  assume(~not_sev == p_GetShortExpVector(p, r));
+
+  if (r == currRing)
+  {
+    loop
+    {
+      if (j > pos) return NULL;
+#if defined(PDEBUG) || defined(PDIV_DEBUG)
+      if (p_LmShortDivisibleBy(strat->S[j], sev[j], p, not_sev, r) &&
+          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
+        break;
+#else
+      if (!(sev[j] & not_sev) &&
+          (ecart== LONG_MAX || ecart>= strat->ecartS[j]) &&
+          p_LmDivisibleBy(strat->S[j], p, r))
+        break;
+
+#endif
+      j++;
+    }
+    // if called from NF, T objects do not exist:
+    if (strat->tl < 0 || strat->S_2_R[j] == -1)
+    {
+      T->Set(strat->S[j], r, strat->tailRing);
+      return T;
+    }
+    else
+    {
+      assume (j >= 0 && j <= strat->tl && strat->S_2_T(j) != NULL &&
+              strat->S_2_T(j)->p == strat->S[j]);
+      return strat->S_2_T(j);
+    }
+  }
+  else
+  {
+    TObject* t;
+    loop
+    {
+      if (j > pos) return NULL;
+      assume(strat->S_2_R[j] != -1);
+#if defined(PDEBUG) || defined(PDIV_DEBUG)
+      t = strat->S_2_T(j);
+      assume(t != NULL && t->t_p != NULL && t->tailRing == r);
+      if (p_LmShortDivisibleBy(t->t_p, sev[j], p, not_sev, r) &&
+          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
+        return t;
+#else
+      if (! (sev[j] & not_sev) && (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
+      {
+        t = strat->S_2_T(j);
+        assume(t != NULL && t->t_p != NULL && t->tailRing == r && t->p == strat->S[j]);
+        if (p_LmDivisibleBy(t->t_p, p, r)) return t;
+      }
+#endif
+      j++;
+    }
+  }
+}
+
+
+poly redtail (LObject* L, int pos, kStrategy strat)
+{
+  poly h, hn;
+  int j;
+  unsigned long not_sev;
+  strat->redTailChange=FALSE;
+
+  poly p = L->p;
+  if (strat->noTailReduction || pNext(p) == NULL)
+    return p;
+
+  LObject Ln(strat->tailRing);
+  TObject* With;
+  // placeholder in case strat->tl < 0
+  TObject  With_s(strat->tailRing);
+  h = p;
+  hn = pNext(h);
+  long op = strat->tailRing->pFDeg(hn, strat->tailRing);
+  long e;
+  int l;
+  BOOLEAN save_HE=strat->kHEdgeFound;
+  strat->kHEdgeFound |=
+    ((Kstd1_deg>0) && (op<=Kstd1_deg)) || TEST_OPT_INFREDTAIL;
+
+  while(hn != NULL)
+  {
+    op = strat->tailRing->pFDeg(hn, strat->tailRing);
+    if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
+    e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
+    loop
+    {
+      Ln.Set(hn, strat->tailRing);
+      Ln.sev = p_GetShortExpVector(hn, strat->tailRing);
+      if (strat->kHEdgeFound)
+        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
+      else
+        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s, e);
+      if (With == NULL) break;
+      strat->redTailChange=TRUE;
+      if (ksReducePolyTail(L, With, h, strat->kNoetherTail()))
+      {
+        // reducing the tail would violate the exp bound
+        if (kStratChangeTailRing(strat, L))
+        {
+          strat->kHEdgeFound = save_HE;
+          return redtail(L, pos, strat);
+        }
+        else
+          return NULL;
+      }
+      hn = pNext(h);
+      if (hn == NULL) goto all_done;
+      op = strat->tailRing->pFDeg(hn, strat->tailRing);
+      if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
+      e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
+    }
+    h = hn;
+    hn = pNext(h);
+  }
+
+  all_done:
+  if (strat->redTailChange)
+  {
+    L->last = 0;
+    L->pLength = 0;
+  }
+  strat->kHEdgeFound = save_HE;
+  return p;
+}
+
+poly redtail (poly p, int pos, kStrategy strat)
+{
+  LObject L(p, currRing);
+  return redtail(&L, pos, strat);
+}
+
+poly redtailBba (LObject* L, int pos, kStrategy strat, BOOLEAN withT)
+{
+  strat->redTailChange=FALSE;
+  if (strat->noTailReduction) return L->GetLmCurrRing();
+  poly h, p;
+  p = h = L->GetLmTailRing();
+  if ((h==NULL) || (pNext(h)==NULL))
+    return L->GetLmCurrRing();
+
+  TObject* With;
+  // placeholder in case strat->tl < 0
+  TObject  With_s(strat->tailRing);
+
+  LObject Ln(pNext(h), strat->tailRing);
+  Ln.pLength = L->GetpLength() - 1;
+
+  pNext(h) = NULL;
+  if (L->p != NULL) pNext(L->p) = NULL;
+  L->pLength = 1;
+
+  Ln.PrepareRed(strat->use_buckets);
+
+  while(!Ln.IsNull())
+  {
+    loop
+    {
+      Ln.SetShortExpVector();
+      if (! withT)
+      {
+        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
+        if (With == NULL) break;
+      }
+      else
+      {
+        int j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
+        if (j < 0) break;
+        With = &(strat->T[j]);
+      }
+      if (ksReducePolyTail(L, With, &Ln))
+      {
+        // reducing the tail would violate the exp bound
+        pNext(h) = Ln.GetTP();
+        L->pLength += Ln.GetpLength();
+        if (L->p != NULL) pNext(L->p) = pNext(p);
+        if (kStratChangeTailRing(strat, L))
+          return redtailBba(L, pos, strat, withT);
+        else
+        { // should never get here -- need to fix this
+          assume(0);
+          return NULL;
+        }
+      }
+      strat->redTailChange=TRUE;
+      if (Ln.IsNull()) goto all_done;
+      if (! withT) With_s.Init(currRing);
+    }
+    pNext(h) = Ln.LmExtractAndIter();
+    pIter(h);
+    L->pLength++;
+  }
+
+  all_done:
+  if (L->p != NULL) pNext(L->p) = pNext(p);
+  assume(pLength(L->p != NULL ? L->p : L->t_p) == L->pLength);
+
+  if (strat->redTailChange)
+  {
+    L->last = NULL;
+    L->length = 0;
+  }
+  kTest_L(L);
+  return L->GetLmCurrRing();
+}
+
+/*2
+*checks the change degree and write progress report
+*/
+void message (int i,int* reduc,int* olddeg,kStrategy strat, int red_result)
+{
+  if (i != *olddeg)
+  {
+    Print("%d",i);
+    *olddeg = i;
+  }
+  if (K_TEST_OPT_OLDSTD)
+  {
+    if (strat->Ll != *reduc)
+    {
+      if (strat->Ll != *reduc-1)
+        Print("(%d)",strat->Ll+1);
+      else
+        PrintS("-");
+      *reduc = strat->Ll;
+    }
+    else
+      PrintS(".");
+    mflush();
+  }
+  else
+  {
+    if (red_result == 0)
+      PrintS("-");
+    else if (red_result < 0)
+      PrintS(".");
+    if ((red_result > 0) || ((strat->Ll % 100)==99))
+    {
+      if (strat->Ll != *reduc && strat->Ll > 0)
+      {
+        Print("(%d)",strat->Ll+1);
+        *reduc = strat->Ll;
+      }
+    }
+  }
+}
+
+/*2
+*statistics
+*/
+void messageStat (int srmax,int lrmax,int hilbcount,kStrategy strat)
+{
+  //PrintS("\nUsage/Allocation of temporary storage:\n");
+  //Print("%d/%d polynomials in standard base\n",srmax,IDELEMS(Shdl));
+  //Print("%d/%d polynomials in set L (for lazy alg.)",lrmax+1,strat->Lmax);
+  Print("\nproduct criterion:%d chain criterion:%d\n",strat->cp,strat->c3);
+  if (hilbcount!=0) Print("hilbert series criterion:%d\n",hilbcount);
+  /*mflush();*/
+}
+
+#ifdef KDEBUG
+/*2
+*debugging output: all internal sets, if changed
+*for testing purpuse only/has to be changed for later use
+*/
+void messageSets (kStrategy strat)
+{
+  int i;
+  if (strat->news)
+  {
+    PrintS("set S");
+    for (i=0; i<=strat->sl; i++)
+    {
+      Print("\n  %d:",i);
+      p_wrp(strat->S[i], currRing, strat->tailRing);
+    }
+    strat->news = FALSE;
+  }
+  if (strat->newt)
+  {
+    PrintS("\nset T");
+    for (i=0; i<=strat->tl; i++)
+    {
+      Print("\n  %d:",i);
+      strat->T[i].wrp();
+      Print(" o:%d e:%d l:%d",
+        strat->T[i].pFDeg(),strat->T[i].ecart,strat->T[i].length);
+    }
+    strat->newt = FALSE;
+  }
+  PrintS("\nset L");
+  for (i=strat->Ll; i>=0; i--)
+  {
+    Print("\n%d:",i);
+    p_wrp(strat->L[i].p1, currRing, strat->tailRing);
+    PrintS("  ");
+    p_wrp(strat->L[i].p2, currRing, strat->tailRing);
+    PrintS(" lcm: ");p_wrp(strat->L[i].lcm, currRing);
+    PrintS("\n  p : ");
+    strat->L[i].wrp();
+    Print("  o:%d e:%d l:%d",
+          strat->L[i].pFDeg(),strat->L[i].ecart,strat->L[i].length);
+  }
+  PrintLn();
+}
+
+#endif
+
+
+/*2
+*construct the set s from F
+*/
+void initS (ideal F, ideal Q,kStrategy strat)
+{
+  int   i,pos;
+
+  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
+  else i=setmaxT;
+  strat->ecartS=initec(i);
+  strat->sevS=initsevS(i);
+  strat->S_2_R=initS_2_R(i);
+  strat->fromQ=NULL;
+  strat->Shdl=idInit(i,F->rank);
+  strat->S=strat->Shdl->m;
+  /*- put polys into S -*/
+  if (Q!=NULL)
+  {
+    strat->fromQ=initec(i);
+    memset(strat->fromQ,0,i*sizeof(int));
+    for (i=0; i<IDELEMS(Q); i++)
+    {
+      if (Q->m[i]!=NULL)
+      {
+        LObject h;
+        h.p = pCopy(Q->m[i]);
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          //pContent(h.p);
+          h.pCleardenom(); // also does a pContent
+        }
+        else
+        {
+          h.pNorm();
+        }
+        strat->initEcart(&h);
+        if (pOrdSgn==-1)
+        {
+          deleteHC(&h, strat);
+        }
+        if (h.p!=NULL)
+        {
+          if (strat->sl==-1)
+            pos =0;
+          else
+          {
+            pos = posInS(strat,strat->sl,h.p,h.ecart);
+          }
+          h.sev = pGetShortExpVector(h.p);
+          strat->enterS(h,pos,strat);
+          strat->fromQ[pos]=1;
+        }
+      }
+    }
+  }
+  for (i=0; i<IDELEMS(F); i++)
+  {
+    if (F->m[i]!=NULL)
+    {
+      LObject h;
+      h.p = pCopy(F->m[i]);
+      if (TEST_OPT_INTSTRATEGY)
+      {
+        //pContent(h.p);
+        h.pCleardenom(); // also does a pContent
+      }
+      else
+      {
+        h.pNorm();
+      }
+      strat->initEcart(&h);
+      if (pOrdSgn==-1)
+      {
+        cancelunit(&h);  /*- tries to cancel a unit -*/
+        deleteHC(&h, strat);
+      }
+      if (h.p!=NULL)
+      {
+        if (strat->sl==-1)
+          pos =0;
+        else
+          pos = posInS(strat,strat->sl,h.p,h.ecart);
+        h.sev = pGetShortExpVector(h.p);
+        strat->enterS(h,pos,strat);
+      }
+    }
+  }
+  /*- test, if a unit is in F -*/
+  if ((strat->sl>=0) && pIsConstant(strat->S[0]))
+  {
+    while (strat->sl>0) deleteInS(strat->sl,strat);
+  }
+}
+
+void initSL (ideal F, ideal Q,kStrategy strat)
+{
+  int   i,pos;
+
+  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
+  else i=setmaxT;
+  strat->ecartS=initec(i);
+  strat->sevS=initsevS(i);
+  strat->S_2_R=initS_2_R(i);
+  strat->fromQ=NULL;
+  strat->Shdl=idInit(i,F->rank);
+  strat->S=strat->Shdl->m;
+  /*- put polys into S -*/
+  if (Q!=NULL)
+  {
+    strat->fromQ=initec(i);
+    memset(strat->fromQ,0,i*sizeof(int));
+    for (i=0; i<IDELEMS(Q); i++)
+    {
+      if (Q->m[i]!=NULL)
+      {
+        LObject h;
+        h.p = pCopy(Q->m[i]);
+        if (TEST_OPT_INTSTRATEGY)
+        {
+          //pContent(h.p);
+          h.pCleardenom(); // also does a pContent
+        }
+        else
+        {
+          h.pNorm();
+        }
+        strat->initEcart(&h);
+        if (pOrdSgn==-1)
+        {
+          deleteHC(&h,strat);
+        }
+        if (h.p!=NULL)
+        {
+          if (strat->sl==-1)
+            pos =0;
+          else
+          {
+            pos = posInS(strat,strat->sl,h.p,h.ecart);
+          }
+          h.sev = pGetShortExpVector(h.p);
+          strat->enterS(h,pos,strat);
+          strat->fromQ[pos]=1;
+        }
+      }
+    }
+  }
+  for (i=0; i<IDELEMS(F); i++)
+  {
+    if (F->m[i]!=NULL)
+    {
+      LObject h;
+      h.p = pCopy(F->m[i]);
+      if (TEST_OPT_INTSTRATEGY)
+      {
+        //pContent(h.p);
+        h.pCleardenom(); // also does a pContent
+      }
+      else
+      {
+        h.pNorm();
+      }
+      strat->initEcart(&h);
+      if (pOrdSgn==-1)
+      {
+        cancelunit(&h);  /*- tries to cancel a unit -*/
+        deleteHC(&h, strat);
+      }
+      if (h.p!=NULL)
+      {
+        if (strat->Ll==-1)
+          pos =0;
+        else
+            pos = strat->posInL(strat->L,strat->Ll,&h,strat);
+        h.sev = pGetShortExpVector(h.p);
+        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
+      }
+    }
+  }
+  /*- test, if a unit is in F -*/
+  if ((strat->Ll>=0) && pIsConstant(strat->L[strat->Ll].p))
+  {
+    while (strat->Ll>0) deleteInL(strat->L,&strat->Ll,strat->Ll-1,strat);
+  }
+}
+
+
+/*2
+*construct the set s from F and {P}
+*/
+void initSSpecial (ideal F, ideal Q, ideal P,kStrategy strat)
+{
+  int   i,pos;
+
+  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
+  else i=setmaxT;
+  i=((i+IDELEMS(F)+15)/16)*16;
+  strat->ecartS=initec(i);
+  strat->sevS=initsevS(i);
+  strat->S_2_R=initS_2_R(i);
+  strat->fromQ=NULL;
+  strat->Shdl=idInit(i,F->rank);
+  strat->S=strat->Shdl->m;
+
+  /*- put polys into S -*/
+  if (Q!=NULL)
+  {
+    strat->fromQ=initec(i);
+    memset(strat->fromQ,0,i*sizeof(int));
+    for (i=0; i<IDELEMS(Q); i++)
+    {
+      if (Q->m[i]!=NULL)
+      {
+        LObject h;
+        h.p = pCopy(Q->m[i]);
+        //if (TEST_OPT_INTSTRATEGY)
+        //{
+        //  //pContent(h.p);
+        //  h.pCleardenom(); // also does a pContent
+        //}
+        //else
+        //{
+        //  h.pNorm();
+        //}
+        strat->initEcart(&h);
+        if (pOrdSgn==-1)
+        {
+          deleteHC(&h,strat);
+        }
+        if (h.p!=NULL)
+        {
+          if (strat->sl==-1)
+            pos =0;
+          else
+          {
+            pos = posInS(strat,strat->sl,h.p,h.ecart);
+          }
+          h.sev = pGetShortExpVector(h.p);
+          h.SetpFDeg();
+          strat->enterS(h,pos,strat, strat->tl+1);
+          enterT(h, strat);
+          strat->fromQ[pos]=1;
+        }
+      }
+    }
+  }
+  /*- put polys into S -*/
+  for (i=0; i<IDELEMS(F); i++)
+  {
+    if (F->m[i]!=NULL)
+    {
+      LObject h;
+      h.p = pCopy(F->m[i]);
+      if (pOrdSgn==1)
+      {
+        h.p=redtailBba(h.p,strat->sl,strat);
+      }
+      strat->initEcart(&h);
+      if (pOrdSgn==-1)
+      {
+        deleteHC(&h,strat);
+      }
+      if (h.p!=NULL)
+      {
+        if (strat->sl==-1)
+          pos =0;
+        else
+          pos = posInS(strat,strat->sl,h.p,h.ecart);
+        h.sev = pGetShortExpVector(h.p);
+        strat->enterS(h,pos,strat, strat->tl+1);
+        h.length = pLength(h.p);
+        h.SetpFDeg();
+        enterT(h,strat);
+      }
+    }
+  }
+  for (i=0; i<IDELEMS(P); i++)
+  {
+    if (P->m[i]!=NULL)
+    {
+      LObject h;
+      h.p=pCopy(P->m[i]);
+      strat->initEcart(&h);
+      h.length = pLength(h.p);
+      if (TEST_OPT_INTSTRATEGY)
+      {
+        h.pCleardenom();
+      }
+      else
+      {
+        h.pNorm();
+      }
+      if(strat->sl>=0)
+      {
+        if (pOrdSgn==1)
+        {
+          h.p=redBba(h.p,strat->sl,strat);
+          if (h.p!=NULL)
+            h.p=redtailBba(h.p,strat->sl,strat);
+        }
+        else
+        {
+          h.p=redMora(h.p,strat->sl,strat);
+          strat->initEcart(&h);
+        }
+        if(h.p!=NULL)
+        {
+          if (TEST_OPT_INTSTRATEGY)
+          {
+            h.pCleardenom();
+          }
+          else
+          {
+            h.is_normalized = 0;
+            h.pNorm();
+          }
+          h.sev = pGetShortExpVector(h.p);
+          h.SetpFDeg();
+          pos = posInS(strat,strat->sl,h.p,h.ecart);
+          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
+          strat->enterS(h,pos,strat, strat->tl+1);
+          enterT(h,strat);
+        }
+      }
+      else
+      {
+        h.sev = pGetShortExpVector(h.p);
+        h.SetpFDeg();
+        strat->enterS(h,0,strat, strat->tl+1);
+        enterT(h,strat);
+      }
+    }
+  }
+}
+/*2
+* reduces h using the set S
+* procedure used in cancelunit1
+*/
+static poly redBba1 (poly h,int maxIndex,kStrategy strat)
+{
+  int j = 0;
+  unsigned long not_sev = ~ pGetShortExpVector(h);
+
+  while (j <= maxIndex)
+  {
+    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j],h, not_sev))
+       return ksOldSpolyRedNew(strat->S[j],h,strat->kNoetherTail());
+    else j++;
+  }
+  return h;
+}
+
+/*2
+*tests if p.p=monomial*unit and cancels the unit
+*/
+void cancelunit1 (LObject* p,int *suc, int index,kStrategy strat )
+{
+  int k;
+  poly r,h,h1,q;
+
+  if (!pIsVector((*p).p) && ((*p).ecart != 0))
+  {
+    k = 0;
+    h1 = r = pCopy((*p).p);
+    h =pNext(r);
+    loop
+    {
+      if (h==NULL)
+      {
+        pDelete(&r);
+        pDelete(&(pNext((*p).p)));
+        (*p).ecart = 0;
+        (*p).length = 1;
+        (*suc)=0;
+        return;
+      }
+      if (!pDivisibleBy(r,h))
+      {
+        q=redBba1(h,index ,strat);
+        if (q != h)
+        {
+          k++;
+          pDelete(&h);
+          pNext(h1) = h = q;
+        }
+        else
+        {
+          pDelete(&r);
+          return;
+        }
+      }
+      else
+      {
+        h1 = h;
+        pIter(h);
+      }
+      if (k > 10)
+      {
+        pDelete(&r);
+        return;
+      }
+    }
+  }
+}
+
+/*2
+* reduces h using the elements from Q in the set S
+* procedure used in updateS
+* must not be used for elements of Q or elements of an ideal !
+*/
+static poly redQ (poly h, int j, kStrategy strat)
+{
+  int start;
+  unsigned long not_sev = ~ pGetShortExpVector(h);
+  while ((j <= strat->sl) && (pGetComp(strat->S[j])!=0)) j++;
+  start=j;
+  while (j<=strat->sl)
+  {
+    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
+    {
+      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
+      if (h==NULL) return NULL;
+      j = start;
+      not_sev = ~ pGetShortExpVector(h);
+    }
+    else j++;
+  }
+  return h;
+}
+
+/*2
+* reduces h using the set S
+* procedure used in updateS
+*/
+static poly redBba (poly h,int maxIndex,kStrategy strat)
+{
+  int j = 0;
+  unsigned long not_sev = ~ pGetShortExpVector(h);
+
+  while (j <= maxIndex)
+  {
+    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
+    {
+      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
+      if (h==NULL) return NULL;
+      j = 0;
+      not_sev = ~ pGetShortExpVector(h);    }
+    else j++;
+  }
+  return h;
+}
+
+/*2
+* reduces h using the set S
+*e is the ecart of h
+*procedure used in updateS
+*/
+static poly redMora (poly h,int maxIndex,kStrategy strat)
+{
+  int  j=0;
+  int  e,l;
+  unsigned long not_sev = ~ pGetShortExpVector(h);
+
+  if (maxIndex >= 0)
+  {
+    e = pLDeg(h,&l)-pFDeg(h);
+    do
+    {
+      if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev)
+      && ((e >= strat->ecartS[j]) || strat->kHEdgeFound))
+      {
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+          {PrintS("reduce ");wrp(h);Print(" with S[%d] (",j);wrp(strat->S[j]);}
+
+#endif
+        h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
+#ifdef KDEBUG
+        if(TEST_OPT_DEBUG)
+          {PrintS(")\nto "); wrp(h); PrintLn();}
+
+#endif
+        // pDelete(&h);
+        if (h == NULL) return NULL;
+        e = pLDeg(h,&l)-pFDeg(h);
+        j = 0;
+        not_sev = ~ pGetShortExpVector(h);
+      }
+      else j++;
+    }
+    while (j <= maxIndex);
+  }
+  return h;
+}
+
+/*2
+*updates S:
+*the result is a set of polynomials which are in
+*normalform with respect to S
+*/
+void updateS(BOOLEAN toT,kStrategy strat)
+{
+  LObject h;
+  int i, suc=0;
+  poly redSi=NULL;
+//Print("nach initS: updateS start mit sl=%d\n",(strat->sl));
+//  for (i=0; i<=(strat->sl); i++)
+//  {
+//    Print("s%d:",i);
+//    if (strat->fromQ!=NULL) Print("(Q:%d) ",strat->fromQ[i]);
+//    pWrite(strat->S[i]);
+//  }
+  if (pOrdSgn==1)
+  {
+    while (suc != -1)
+    {
+      i=suc+1;
+      while (i<=strat->sl)
+      {
+        if (((strat->syzComp==0) || (pGetComp(strat->S[i])<=strat->syzComp))
+        && ((strat->fromQ==NULL) || (strat->fromQ[i]==0)))
+        {
+          pDelete(&redSi);
+          redSi = pHead(strat->S[i]);
+          strat->S[i] = redBba(strat->S[i],i-1,strat);
+          if ((strat->ak!=0)&&(strat->S[i]!=NULL))
+            strat->S[i]=redQ(strat->S[i],i+1,strat); /*reduce S[i] mod Q*/
+          if (TEST_OPT_DEBUG && (pCmp(redSi,strat->S[i])!=0))
+          {
+            PrintS("reduce:");
+            wrp(redSi);PrintS(" to ");p_wrp(strat->S[i], currRing, strat->tailRing);PrintLn();
+          }
+          if (TEST_OPT_PROT && (pCmp(redSi,strat->S[i])!=0))
+          {
+            if (strat->S[i]==NULL)
+              PrintS("V");
+            else
+              PrintS("v");
+            mflush();
+          }
+          if (strat->S[i]==NULL)
+          {
+            pDelete(&redSi);
+            deleteInS(i,strat);
+            i--;
+          }
+          else
+          {
+            pDelete(&redSi);
+            if (TEST_OPT_INTSTRATEGY)
+            {
+              //pContent(strat->S[i]);
+              pCleardenom(strat->S[i]);// also does a pContent
+            }
+            else
+            {
+              pNorm(strat->S[i]);
+            }
+            strat->sevS[i] = pGetShortExpVector(strat->S[i]);
+          }
+        }
+        i++;
+      }
+      reorderS(&suc,strat);
+    }
+    if (toT)
+    {
+      for (i=0; i<=strat->sl; i++)
+      {
+        if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
+        {
+          h.p = redtailBba(strat->S[i],i-1,strat);
+          if (TEST_OPT_INTSTRATEGY)
+          {
+            pCleardenom(h.p);// also does a pContent
+          }
+        }
+        else
+        {
+          h.p = strat->S[i];
+        }
+        if (strat->honey)
+        {
+          strat->initEcart(&h);
+          strat->ecartS[i] = h.ecart;
+        }
+        if (strat->sevS[i] == 0) {strat->sevS[i] = pGetShortExpVector(h.p);}
+        else assume(strat->sevS[i] == pGetShortExpVector(h.p));
+        h.sev = strat->sevS[i];
+        h.SetpFDeg();
+        /*puts the elements of S also to T*/
+        enterT(h,strat);
+        strat->S_2_R[i] = strat->tl;
+      }
+    }
+  }
+  else
+  {
+    while (suc != -1)
+    {
+      i=suc;
+      while (i<=strat->sl)
+      {
+        if (((strat->syzComp==0) || (pGetComp(strat->S[i])<=strat->syzComp))
+        && ((strat->fromQ==NULL) || (strat->fromQ[i]==0)))
+        {
+          pDelete(&redSi);
+          redSi=pHead((strat->S)[i]);
+          (strat->S)[i] = redMora((strat->S)[i],i-1,strat);
+          if ((strat->S)[i]==NULL)
+          {
+            deleteInS(i,strat);
+            i--;
+          }
+          else
+          {
+            if (TEST_OPT_INTSTRATEGY)
+            {
+              pDelete(&redSi);
+              pCleardenom(strat->S[i]);// also does a pContent
+              h.p = strat->S[i];
+              strat->initEcart(&h);
+              strat->ecartS[i] = h.ecart;
+            }
+            else
+            {
+              pDelete(&redSi);
+              pNorm(strat->S[i]);
+              h.p = strat->S[i];
+              strat->initEcart(&h);
+              strat->ecartS[i] = h.ecart;
+            }
+            h.sev =  pGetShortExpVector(h.p);
+            strat->sevS[i] = h.sev;
+          }
+          kTest(strat);
+        }
+        i++;
+      }
+#ifdef KDEBUG
+      kTest(strat);
+#endif
+      reorderS(&suc,strat);
+      if (h.p!=NULL)
+      {
+        if (!strat->kHEdgeFound)
+        {
+          /*strat->kHEdgeFound =*/ HEckeTest(h.p,strat);
+        }
+        if (strat->kHEdgeFound)
+          newHEdge(strat->S,strat);
+      }
+    }
+    for (i=0; i<=strat->sl; i++)
+    {
+      if (((strat->fromQ==NULL) || (strat->fromQ[i]==0))
+      )
+      {
+        strat->S[i] = h.p = redtail(strat->S[i],strat->sl,strat);
+        strat->initEcart(&h);
+        strat->ecartS[i] = h.ecart;
+        h.sev = pGetShortExpVector(h.p);
+        strat->sevS[i] = h.sev;
+      }
+      else
+      {
+        h.p = strat->S[i];
+        h.ecart=strat->ecartS[i];
+        h.sev = strat->sevS[i];
+      }
+      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
+        cancelunit1(&h,&suc,strat->sl,strat);
+      h.length = pLength(h.p);
+      h.SetpFDeg();
+      /*puts the elements of S also to T*/
+      enterT(h,strat);
+      strat->S_2_R[i] = strat->tl;
+    }
+    if (suc!= -1) updateS(toT,strat);
+  }
+  if (redSi!=NULL) pDeleteLm(&redSi);
+#ifdef KDEBUG
+  kTest(strat);
+#endif
+}
+
+
+/*2
+* -puts p to the standardbasis s at position at
+* -saves the result in S
+*/
+void enterSBba (LObject p,int atS,kStrategy strat, int atR)
+{
+  int i;
+  strat->news = TRUE;
+  /*- puts p to the standardbasis s at position at -*/
+  if (strat->sl == IDELEMS(strat->Shdl)-1)
+  {
+    strat->sevS = (unsigned long*) omRealloc0Size(strat->sevS,
+                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
+                                    (IDELEMS(strat->Shdl)+setmaxTinc)
+                                                  *sizeof(unsigned long));
+    strat->ecartS = (intset)omReallocSize(strat->ecartS,
+                                          IDELEMS(strat->Shdl)*sizeof(int),
+                                          (IDELEMS(strat->Shdl)+setmaxTinc)
+                                                  *sizeof(int));
+    strat->S_2_R = (int*) omRealloc0Size(strat->S_2_R,
+                                         IDELEMS(strat->Shdl)*sizeof(int),
+                                         (IDELEMS(strat->Shdl)+setmaxTinc)
+                                                  *sizeof(int));
+    if (strat->lenS!=NULL)
+      strat->lenS=(int*)omRealloc0Size(strat->lenS,
+                                       IDELEMS(strat->Shdl)*sizeof(int),
+                                       (IDELEMS(strat->Shdl)+setmaxTinc)
+                                                 *sizeof(int));
+    if (strat->lenSw!=NULL)
+      strat->lenSw=(int*)omRealloc0Size(strat->lenSw,
+                                       IDELEMS(strat->Shdl)*sizeof(int),
+                                       (IDELEMS(strat->Shdl)+setmaxTinc)
+                                                 *sizeof(int));
+    if (strat->fromQ!=NULL)
+    {
+      strat->fromQ = (intset)omReallocSize(strat->fromQ,
+                                    IDELEMS(strat->Shdl)*sizeof(int),
+                                    (IDELEMS(strat->Shdl)+setmaxTinc)*sizeof(int));
+    }
+    pEnlargeSet(&strat->S,IDELEMS(strat->Shdl),setmaxTinc);
+    IDELEMS(strat->Shdl)+=setmaxTinc;
+    strat->Shdl->m=strat->S;
+  }
+  if (atS <= strat->sl)
+  {
+#ifdef ENTER_USE_MEMMOVE
+// #if 0
+    memmove(&(strat->S[atS+1]), &(strat->S[atS]),
+            (strat->sl - atS + 1)*sizeof(poly));
+    memmove(&(strat->ecartS[atS+1]), &(strat->ecartS[atS]),
+            (strat->sl - atS + 1)*sizeof(int));
+    memmove(&(strat->sevS[atS+1]), &(strat->sevS[atS]),
+            (strat->sl - atS + 1)*sizeof(unsigned long));
+    memmove(&(strat->S_2_R[atS+1]), &(strat->S_2_R[atS]),
+            (strat->sl - atS + 1)*sizeof(int));
+    if (strat->lenS!=NULL)
+    memmove(&(strat->lenS[atS+1]), &(strat->lenS[atS]),
+            (strat->sl - atS + 1)*sizeof(int));
+    if (strat->lenSw!=NULL)
+    memmove(&(strat->lenSw[atS+1]), &(strat->lenSw[atS]),
+            (strat->sl - atS + 1)*sizeof(int));
+#else
+    for (i=strat->sl+1; i>=atS+1; i--)
+    {
+      strat->S[i] = strat->S[i-1];
+      strat->ecartS[i] = strat->ecartS[i-1];
+      strat->sevS[i] = strat->sevS[i-1];
+      strat->S_2_R[i] = strat->S_2_R[i-1];
+    }
+    if (strat->lenS!=NULL)
+    for (i=strat->sl+1; i>=atS+1; i--)
+      strat->lenS[i] = strat->lenS[i-1];
+    if (strat->lenSw!=NULL)
+    for (i=strat->sl+1; i>=atS+1; i--)
+      strat->lenSw[i] = strat->lenSw[i-1];
+#endif
+  }
+  if (strat->fromQ!=NULL)
+  {
+#ifdef ENTER_USE_MEMMOVE
+    memmove(&(strat->fromQ[atS+1]), &(strat->fromQ[atS]),
+                  (strat->sl - atS + 1)*sizeof(int));
+#else
+    for (i=strat->sl+1; i>=atS+1; i--)
+    {
+      strat->fromQ[i] = strat->fromQ[i-1];
+    }
+#endif
+    strat->fromQ[atS]=0;
+  }
+
+  /*- save result -*/
+  strat->S[atS] = p.p;
+  if (strat->honey) strat->ecartS[atS] = p.ecart;
+  if (p.sev == 0)
+    p.sev = pGetShortExpVector(p.p);
+  else
+    assume(p.sev == pGetShortExpVector(p.p));
+  strat->sevS[atS] = p.sev;
+  strat->ecartS[atS] = p.ecart;
+  strat->S_2_R[atS] = atR;
+  strat->sl++;
+}
+
+/*2
+* puts p to the set T at position atT
+*/
+void enterT(LObject p, kStrategy strat, int atT)
+{
+  int i;
+
+  pp_Test(p.p, currRing, p.tailRing);
+  assume(strat->tailRing == p.tailRing);
+  // redMoraNF complains about this -- but, we don't really
+  // neeed this so far
+  // assume(p.pLength == 0 || pLength(p.p) == p.pLength);
+  assume(p.FDeg == p.pFDeg());
+  assume(!p.is_normalized || nIsOne(pGetCoeff(p.p)));
+
+  strat->newt = TRUE;
+  if (atT < 0)
+    atT = strat->posInT(strat->T, strat->tl, p);
+  if (strat->tl == strat->tmax-1)
+    enlargeT(strat->T,strat->R,strat->sevT,strat->tmax,setmaxTinc);
+  if (atT <= strat->tl)
+  {
+#ifdef ENTER_USE_MEMMOVE
+    memmove(&(strat->T[atT+1]), &(strat->T[atT]),
+            (strat->tl-atT+1)*sizeof(TObject));
+    memmove(&(strat->sevT[atT+1]), &(strat->sevT[atT]),
+            (strat->tl-atT+1)*sizeof(unsigned long));
+#endif
+    for (i=strat->tl+1; i>=atT+1; i--)
+    {
+#ifndef ENTER_USE_MEMMOVE
+      strat->T[i] = strat->T[i-1];
+      strat->sevT[i] = strat->sevT[i-1];
+#endif
+      strat->R[strat->T[i].i_r] = &(strat->T[i]);
+    }
+  }
+
+  if (strat->tailBin != NULL && (pNext(p.p) != NULL))
+  {
+    pNext(p.p)=p_ShallowCopyDelete(pNext(p.p),
+                                   (strat->tailRing != NULL ?
+                                    strat->tailRing : currRing),
+                                   strat->tailBin);
+    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
+  }
+  strat->T[atT] = (TObject) p;
+
+  if (strat->tailRing != currRing && pNext(p.p) != NULL)
+    strat->T[atT].max = p_GetMaxExpP(pNext(p.p), strat->tailRing);
+  else
+    strat->T[atT].max = NULL;
+
+  strat->tl++;
+  strat->R[strat->tl] = &(strat->T[atT]);
+  strat->T[atT].i_r = strat->tl;
+  assume(p.sev == 0 || pGetShortExpVector(p.p) == p.sev);
+  strat->sevT[atT] = (p.sev == 0 ? pGetShortExpVector(p.p) : p.sev);
+  kTest_T(&(strat->T[atT]));
+}
+
+void initHilbCrit(ideal F, ideal Q, intvec **hilb,kStrategy strat)
+{
+  if (strat->homog!=isHomog)
+  {
+    *hilb=NULL;
+  }
+}
+
+void initBuchMoraCrit(kStrategy strat)
+{
+  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
+  // obachman: Hmm.. I need BTEST1(2) for notBuckets ..
+  //  strat->Gebauer =          BTEST1(2) || strat->homog || strat->sugarCrit;
+  strat->Gebauer =          strat->homog || strat->sugarCrit;
+  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
+  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
+  strat->pairtest = NULL;
+  /* alway use tailreduction, except:
+  * - in local rings, - in lex order case, -in ring over extensions */
+  strat->noTailReduction = !TEST_OPT_REDTAIL;
+#ifdef HAVE_PLURAL
+  // and r is plural_ring
+  if (currRing->nc!=NULL)
+    //or it has non-quasi-comm type... later
+  {
+    strat->sugarCrit = FALSE;
+    strat->Gebauer = FALSE ;
+    strat->honey = FALSE;
+  }
+#endif
+  if (TEST_OPT_DEBUG)
+  {
+    if (strat->homog) PrintS("ideal/module is homogeneous\n");
+    else              PrintS("ideal/module is not homogeneous\n");
+  }
+}
+
+BOOLEAN kPosInLDependsOnLength(int (*pos_in_l)
+                               (const LSet set, const int length,
+                                LObject* L,const kStrategy strat))
+{
+  if (pos_in_l == posInL110 ||
+      pos_in_l == posInL10)
+    return TRUE;
+
+  return FALSE;
+}
+
+void initBuchMoraPos (kStrategy strat)
+{
+  if (pOrdSgn==1)
+  {
+    if (strat->honey)
+    {
+      strat->posInL = posInL15;
+      // ok -- here is the deal: from my experiments for Singular-2-0
+      // I conclude that that posInT_EcartpLength is the best of
+      // posInT15, posInT_EcartFDegpLength, posInT_FDegLength, posInT_pLength
+      // see the table at the end of this file
+      if (K_TEST_OPT_OLDSTD)
+        strat->posInT = posInT15;
+      else
+        strat->posInT = posInT_EcartpLength;
+    }
+    else if (pLexOrder && !TEST_OPT_INTSTRATEGY)
+    {
+      strat->posInL = posInL11;
+      strat->posInT = posInT11;
+    }
+    else if (TEST_OPT_INTSTRATEGY)
+    {
+      strat->posInL = posInL11;
+      strat->posInT = posInT11;
+    }
+    else
+    {
+      strat->posInL = posInL0;
+      strat->posInT = posInT0;
+    }
+    //if (strat->minim>0) strat->posInL =posInLSpecial;
+  }
+  else
+  {
+    if (strat->homog)
+    {
+      strat->posInL = posInL11;
+      strat->posInT = posInT11;
+    }
+    else
+    {
+      if ((currRing->order[0]==ringorder_c)
+      ||(currRing->order[0]==ringorder_C))
+      {
+        strat->posInL = posInL17_c;
+        strat->posInT = posInT17_c;
+      }
+      else
+      {
+        strat->posInL = posInL17;
+        strat->posInT = posInT17;
+      }
+    }
+  }
+  if (strat->minim>0) strat->posInL =posInLSpecial;
+  // for further tests only
+  if ((BTEST1(11)) || (BTEST1(12)))
+    strat->posInL = posInL11;
+  else if ((BTEST1(13)) || (BTEST1(14)))
+    strat->posInL = posInL13;
+  else if ((BTEST1(15)) || (BTEST1(16)))
+    strat->posInL = posInL15;
+  else if ((BTEST1(17)) || (BTEST1(18)))
+    strat->posInL = posInL17;
+  if (BTEST1(11))
+    strat->posInT = posInT11;
+  else if (BTEST1(13))
+    strat->posInT = posInT13;
+  else if (BTEST1(15))
+    strat->posInT = posInT15;
+  else if ((BTEST1(17)))
+    strat->posInT = posInT17;
+  else if ((BTEST1(19)))
+    strat->posInT = posInT19;
+  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
+    strat->posInT = posInT1;
+  strat->posInLDependsOnLength = kPosInLDependsOnLength(strat->posInL);
+}
+
+void initBuchMora (ideal F,ideal Q,kStrategy strat)
+{
+  strat->interpt = BTEST1(OPT_INTERRUPT);
+  strat->kHEdge=NULL;
+  if (pOrdSgn==1) strat->kHEdgeFound=FALSE;
+  /*- creating temp data structures------------------- -*/
+  strat->cp = 0;
+  strat->c3 = 0;
+  strat->tail = pInit();
+  /*- set s -*/
+  strat->sl = -1;
+  /*- set L -*/
+  strat->Lmax = setmaxL;
+  strat->Ll = -1;
+  strat->L = initL();
+  /*- set B -*/
+  strat->Bmax = setmaxL;
+  strat->Bl = -1;
+  strat->B = initL();
+  /*- set T -*/
+  strat->tl = -1;
+  strat->tmax = setmaxT;
+  strat->T = initT();
+  strat->R = initR();
+  strat->sevT = initsevT();
+  /*- init local data struct.---------------------------------------- -*/
+  strat->P.ecart=0;
+  strat->P.length=0;
+  if (pOrdSgn==-1)
+  {
+    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
+    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
+  }
+  if(TEST_OPT_SB_1)
+  {
+    int i;
+    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
+    for (i=strat->newIdeal;i<IDELEMS(F);i++)
+    {
+      P->m[i-strat->newIdeal] = F->m[i];
+      F->m[i] = NULL;
+    }
+    initSSpecial(F,Q,P,strat);
+    for (i=strat->newIdeal;i<IDELEMS(F);i++)
+    {
+      F->m[i] = P->m[i-strat->newIdeal];
+      P->m[i-strat->newIdeal] = NULL;
+    }
+    idDelete(&P);
+  }
+  else
+  {
+    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
+    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
+  }
+  strat->kIdeal = NULL;
+  strat->fromT = FALSE;
+  strat->noTailReduction = !TEST_OPT_REDTAIL;
+  if(!TEST_OPT_SB_1)
+  {
+    updateS(TRUE,strat);
+    pairs(strat);
+  }
+  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
+  strat->fromQ=NULL;
+}
+
+void exitBuchMora (kStrategy strat)
+{
+  /*- release temp data -*/
+  cleanT(strat);
+  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
+  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
+  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
+  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
+  omFreeSize(strat->sevS,IDELEMS(strat->Shdl)*sizeof(int));
+  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
+  /*- set L: should be empty -*/
+  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
+  /*- set B: should be empty -*/
+  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
+  pDeleteLm(&strat->tail);
+  strat->syzComp=0;
+  if (strat->kIdeal!=NULL)
+  {
+    omFreeBin(strat->kIdeal, sleftv_bin);
+    strat->kIdeal=NULL;
+  }
+}
+
+/*2
+* in the case of a standardbase of a module over a qring:
+* replace polynomials in i by ak vectors,
+* (the polynomial * unit vectors gen(1)..gen(ak)
+* in every case (also for ideals:)
+* deletes divisible vectors/polynomials
+*/
+void updateResult(ideal r,ideal Q, kStrategy strat)
+{
+  int l;
+  if (strat->ak>0)
+  {
+    for (l=IDELEMS(r)-1;l>=0;l--)
+    {
+      if ((r->m[l]!=NULL) && (pGetComp(r->m[l])==0))
+      {
+        pDelete(&r->m[l]); // and set it to NULL
+      }
+    }
+    int q;
+    poly p;
+    for (l=IDELEMS(r)-1;l>=0;l--)
+    {
+      if (r->m[l]!=NULL)
+      {
+        for(q=IDELEMS(Q)-1; q>=0;q--)
+        {
+          if ((Q->m[q]!=NULL)
+          &&(pLmDivisibleBy(Q->m[q],r->m[l])))
+          {
+            if (TEST_OPT_REDSB)
+            {
+              p=r->m[l];
+              r->m[l]=kNF(Q,NULL,p);
+              pDelete(&p);
+            }
+            else
+            {
+              pDelete(&r->m[l]); // and set it to NULL
+            }
+            break;
+          }
+        }
+      }
+    }
+  }
+  else
+  {
+    int q;
+    poly p;
+    for (l=IDELEMS(r)-1;l>=0;l--)
+    {
+      if (r->m[l]!=NULL)
+      {
+        for(q=IDELEMS(Q)-1; q>=0;q--)
+        {
+          if ((Q->m[q]!=NULL)
+          &&(pLmEqual(r->m[l],Q->m[q])))
+          {
+            if (TEST_OPT_REDSB)
+            {
+              p=r->m[l];
+              r->m[l]=kNF(Q,NULL,p);
+              pDelete(&p);
+            }
+            else
+            {
+              pDelete(&r->m[l]); // and set it to NULL
+            }
+            break;
+          }
+        }
+      }
+    }
+  }
+  idSkipZeroes(r);
+}
+
+void completeReduce (kStrategy strat)
+{
+  int i;
+  int low = (pOrdSgn == 1 ? 1 : 0);
+  LObject L;
+
+#ifdef KDEBUG
+  // need to set this: during tailreductions of T[i], T[i].max is out of
+  // sync
+  sloppy_max = TRUE;
+#endif
+
+  strat->noTailReduction = FALSE;
+  if (TEST_OPT_PROT)
+  {
+    PrintLn();
+    if (timerv) writeTime("standard base computed:");
+  }
+  if (TEST_OPT_PROT)
+  {
+    Print("(S:%d)",strat->sl);mflush();
+  }
+  for (i=strat->sl; i>=low; i--)
+  {
+    TObject* T_j = strat->s_2_t(i);
+    if (T_j != NULL)
+    {
+      L = *T_j;
+      poly p;
+      if (pOrdSgn == 1)
+        strat->S[i] = redtailBba(&L, i-1, strat, FALSE);
+      else
+        strat->S[i] = redtail(&L, strat->sl, strat);
+
+      if (strat->redTailChange && strat->tailRing != currRing)
+      {
+        if (T_j->max != NULL) p_LmFree(T_j->max, strat->tailRing);
+        if (pNext(T_j->p) != NULL)
+          T_j->max = p_GetMaxExpP(pNext(T_j->p), strat->tailRing);
+        else
+          T_j->max = NULL;
+      }
+      if (TEST_OPT_INTSTRATEGY)
+        T_j->pCleardenom();
+    }
+    else
+    {
+      assume(currRing == strat->tailRing);
+      if (pOrdSgn == 1)
+        strat->S[i] = redtailBba(strat->S[i], i-1, strat);
+      else
+        strat->S[i] = redtail(strat->S[i], strat->sl, strat);
+      if (TEST_OPT_INTSTRATEGY)
+        pCleardenom(strat->S[i]);
+    }
+    if (TEST_OPT_PROT)
+      PrintS("-");
+  }
+#ifdef KDEBUG
+  sloppy_max = FALSE;
+#endif
+}
+
+
+/*2
+* computes the new strat->kHEdge and the new pNoether,
+* returns TRUE, if pNoether has changed
+*/
+BOOLEAN newHEdge(polyset S, kStrategy strat)
+{
+  int i,j;
+  poly newNoether;
+
+  scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
+  if (strat->t_kHEdge != NULL) p_LmFree(strat->t_kHEdge, strat->tailRing);
+  if (strat->tailRing != currRing)
+    strat->t_kHEdge = k_LmInit_currRing_2_tailRing(strat->kHEdge, strat->tailRing);
+  /* compare old and new noether*/
+  newNoether = pLmInit(strat->kHEdge);
+  j = pFDeg(newNoether);
+  for (i=1; i<=pVariables; i++)
+  {
+    if (pGetExp(newNoether, i) > 0) pDecrExp(newNoether,i);
+  }
+  pSetm(newNoether);
+  if (j < strat->HCord) /*- statistics -*/
+  {
+    if (TEST_OPT_PROT)
+    {
+      Print("H(%d)",j);
+      mflush();
+    }
+    strat->HCord=j;
+    if (TEST_OPT_DEBUG)
+    {
+      Print("H(%d):",j);
+      wrp(strat->kHEdge);
+      PrintLn();
+    }
+  }
+  if (pCmp(strat->kNoether,newNoether)!=1)
+  {
+    pDelete(&strat->kNoether);
+    strat->kNoether=newNoether;
+    if (strat->t_kNoether != NULL) p_LmFree(strat->t_kNoether, strat->tailRing);
+    if (strat->tailRing != currRing)
+      strat->t_kNoether = k_LmInit_currRing_2_tailRing(strat->kNoether, strat->tailRing);
+
+    return TRUE;
+  }
+  pLmFree(newNoether);
+  return FALSE;
+}
+
+/***************************************************************
+ *
+ * Routines related for ring changes during std computations
+ *
+ ***************************************************************/
+BOOLEAN kCheckSpolyCreation(LObject *L, kStrategy strat, poly &m1, poly &m2)
+{
+  assume(L->p1 != NULL && L->p2 != NULL);
+  assume(L->i_r1 >= 0 && L->i_r1 <= strat->tl);
+  assume(L->i_r2 >= 0 && L->i_r2 <= strat->tl);
+  assume(strat->tailRing != currRing);
+
+  if (! k_GetLeadTerms(L->p1, L->p2, currRing, m1, m2, strat->tailRing))
+    return FALSE;
+  poly p1_max = (strat->R[L->i_r1])->max;
+  poly p2_max = (strat->R[L->i_r2])->max;
+
+  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
+      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
+  {
+    p_LmFree(m1, strat->tailRing);
+    p_LmFree(m2, strat->tailRing);
+    m1 = NULL;
+    m2 = NULL;
+    return FALSE;
+  }
+  return TRUE;
+}
+
+BOOLEAN kStratChangeTailRing(kStrategy strat, LObject *L, TObject* T, unsigned long expbound)
+{
+  if (expbound == 0) expbound = strat->tailRing->bitmask << 1;
+  if (expbound >= currRing->bitmask) return FALSE;
+  ring new_tailRing = rModifyRing(currRing,
+                                  // Hmmm .. the condition pFDeg == pDeg
+                                  // might be too strong
+                                  (strat->homog && pFDeg == pDeg),
+                                  !strat->ak,
+                                  expbound);
+  if (new_tailRing == currRing) return TRUE;
+
+  strat->pOrigFDeg_TailRing = new_tailRing->pFDeg;
+  strat->pOrigLDeg_TailRing = new_tailRing->pLDeg;
+
+  if (currRing->pFDeg != currRing->pFDegOrig)
+  {
+    new_tailRing->pFDeg = currRing->pFDeg;
+    new_tailRing->pLDeg = currRing->pLDeg;
+  }
+
+  if (TEST_OPT_PROT)
+    Print("[%lu:%d", (unsigned long) new_tailRing->bitmask, new_tailRing->ExpL_Size);
+  kTest_TS(strat);
+  assume(new_tailRing != strat->tailRing);
+  pShallowCopyDeleteProc p_shallow_copy_delete
+    = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
+
+  omBin new_tailBin = omGetStickyBinOfBin(new_tailRing->PolyBin);
+
+  int i;
+  for (i=0; i<=strat->tl; i++)
+  {
+    strat->T[i].ShallowCopyDelete(new_tailRing, new_tailBin,
+                                  p_shallow_copy_delete);
+  }
+  for (i=0; i<=strat->Ll; i++)
+  {
+    assume(strat->L[i].p != NULL);
+    if (pNext(strat->L[i].p) != strat->tail)
+      strat->L[i].ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
+  }
+  if (strat->P.t_p != NULL ||
+      (strat->P.p != NULL && pNext(strat->P.p) != strat->tail))
+    strat->P.ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
+
+  if (L != NULL && L->tailRing != new_tailRing)
+  {
+    if (L->i_r < 0)
+      L->ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
+    else
+    {
+      assume(L->i_r <= strat->tl);
+      TObject* t_l = strat->R[L->i_r];
+      assume(t_l != NULL);
+      L->tailRing = new_tailRing;
+      L->p = t_l->p;
+      L->t_p = t_l->t_p;
+      L->max = t_l->max;
+    }
+  }
+
+  if (T != NULL && T->tailRing != new_tailRing && T->i_r < 0)
+    T->ShallowCopyDelete(new_tailRing, new_tailBin, p_shallow_copy_delete);
+
+  omMergeStickyBinIntoBin(strat->tailBin, strat->tailRing->PolyBin);
+  if (strat->tailRing != currRing)
+    rKillModifiedRing(strat->tailRing);
+
+  strat->tailRing = new_tailRing;
+  strat->tailBin = new_tailBin;
+  strat->p_shallow_copy_delete
+    = pGetShallowCopyDeleteProc(currRing, new_tailRing);
+
+  if (strat->kHEdge != NULL)
+  {
+    if (strat->t_kHEdge != NULL)
+      p_LmFree(strat->t_kHEdge, strat->tailRing);
+    strat->t_kHEdge=k_LmInit_currRing_2_tailRing(strat->kHEdge, new_tailRing);
+  }
+
+  if (strat->kNoether != NULL)
+  {
+    if (strat->t_kNoether != NULL)
+      p_LmFree(strat->t_kNoether, strat->tailRing);
+    strat->t_kNoether=k_LmInit_currRing_2_tailRing(strat->kNoether,
+                                                   new_tailRing);
+  }
+  kTest_TS(strat);
+  if (TEST_OPT_PROT)
+    PrintS("]");
+  return TRUE;
+}
+
+void kStratInitChangeTailRing(kStrategy strat)
+{
+  unsigned long l = 0;
+  int i;
+  Exponent_t e;
+  ring new_tailRing;
+
+  assume(strat->tailRing == currRing);
+
+  for (i=0; i<= strat->Ll; i++)
+  {
+    l = p_GetMaxExpL(strat->L[i].p, currRing, l);
+  }
+  for (i=0; i<=strat->tl; i++)
+  {
+    // Hmm ... this we could do in one Step
+    l = p_GetMaxExpL(strat->T[i].p, currRing, l);
+  }
+  e = p_GetMaxExp(l, currRing);
+  if (e <= 1) e = 2;
+
+  kStratChangeTailRing(strat, NULL, NULL, e);
+}
+
+skStrategy::skStrategy()
+{
+  memset(this, 0, sizeof(skStrategy));
+  tailRing = currRing;
+  P.tailRing = currRing;
+  tl = -1;
+  sl = -1;
+#ifdef HAVE_LM_BIN
+  lmBin = omGetStickyBinOfBin(currRing->PolyBin);
+#endif
+#ifdef HAVE_TAIL_BIN
+  tailBin = omGetStickyBinOfBin(currRing->PolyBin);
+#endif
+  pOrigFDeg = pFDeg;
+  pOrigLDeg = pLDeg;
+}
+
+
+skStrategy::~skStrategy()
+{
+  if (lmBin != NULL)
+    omMergeStickyBinIntoBin(lmBin, currRing->PolyBin);
+  if (tailBin != NULL)
+    omMergeStickyBinIntoBin(tailBin,
+                            (tailRing != NULL ? tailRing->PolyBin:
+                             currRing->PolyBin));
+  if (t_kHEdge != NULL)
+    p_LmFree(t_kHEdge, tailRing);
+  if (t_kNoether != NULL)
+    p_LmFree(t_kNoether, tailRing);
+
+  if (currRing != tailRing)
+    rKillModifiedRing(tailRing);
+  pRestoreDegProcs(pOrigFDeg, pOrigLDeg);
+}
+
+#if 0
+Timings for the different possibilities of posInT:
+            T15           EDL         DL          EL            L         1-2-3
+Gonnet      43.26       42.30       38.34       41.98       38.40      100.04
+Hairer_2_1   1.11        1.15        1.04        1.22        1.08        4.7
+Twomat3      1.62        1.69        1.70        1.65        1.54       11.32
+ahml         4.48        4.03        4.03        4.38        4.96       26.50
+c7          15.02       13.98       15.16       13.24       17.31       47.89
+c8         505.09      407.46      852.76      413.21      499.19        n/a
+f855        12.65        9.27       14.97        8.78       14.23       33.12
+gametwo6    11.47       11.35       14.57       11.20       12.02       35.07
+gerhard_3    2.73        2.83        2.93        2.64        3.12        6.24
+ilias13     22.89       22.46       24.62       20.60       23.34       53.86
+noon8       40.68       37.02       37.99       36.82       35.59      877.16
+rcyclic_19  48.22       42.29       43.99       45.35       51.51      204.29
+rkat9       82.37       79.46       77.20       77.63       82.54      267.92
+schwarz_11  16.46       16.81       16.76       16.81       16.72       35.56
+test016     16.39       14.17       14.40       13.50       14.26       34.07
+test017     34.70       36.01       33.16       35.48       32.75       71.45
+test042     10.76       10.99       10.27       11.57       10.45       23.04
+test058      6.78        6.75        6.51        6.95        6.22        9.47
+test066     10.71       10.94       10.76       10.61       10.56       19.06
+test073     10.75       11.11       10.17       10.79        8.63       58.10
+test086     12.23       11.81       12.88       12.24       13.37       66.68
+test103      5.05        4.80        5.47        4.64        4.89       11.90
+test154     12.96       11.64       13.51       12.46       14.61       36.35
+test162     65.27       64.01       67.35       59.79       67.54      196.46
+test164      7.50        6.50        7.68        6.70        7.96       17.13
+virasoro     3.39        3.50        3.35        3.47        3.70        7.66
+#endif
+
+
+#ifdef HAVE_MORE_POS_IN_T
+// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
+int posInT_EcartFDegpLength(const TSet set,const int length,LObject &p)
+{
+
+  if (length==-1) return 0;
+
+  int o = p.ecart;
+  int op=p.GetpFDeg();
+  int ol = p.GetpLength();
+
+  if (set[length].ecart < o)
+    return length+1;
+  if (set[length].ecart == o)
+  {
+     int oo=set[length].GetpFDeg();
+     if ((oo < op) || ((oo==op) && (set[length].length < ol)))
+       return length+1;
+  }
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (set[an].ecart > o)
+        return an;
+      if (set[an].ecart == o)
+      {
+         int oo=set[an].GetpFDeg();
+         if((oo > op)
+         || ((oo==op) && (set[an].pLength > ol)))
+           return an;
+      }
+      return en;
+    }
+    i=(an+en) / 2;
+    if (set[i].ecart > o)
+      en=i;
+    else if (set[i].ecart == o)
+    {
+       int oo=set[i].GetpFDeg();
+       if ((oo > op)
+       || ((oo == op) && (set[i].pLength > ol)))
+         en=i;
+       else
+        an=i;
+    }
+    else
+      an=i;
+  }
+}
+
+// determines the position based on: 1.) FDeg 2.) pLength
+int posInT_FDegpLength(const TSet set,const int length,LObject &p)
+{
+
+  if (length==-1) return 0;
+
+  int op=p.GetpFDeg();
+  int ol = p.GetpLength();
+
+  int oo=set[length].GetpFDeg();
+  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  loop
+    {
+      if (an >= en-1)
+      {
+        int oo=set[an].GetpFDeg();
+        if((oo > op)
+           || ((oo==op) && (set[an].pLength > ol)))
+          return an;
+        return en;
+      }
+      i=(an+en) / 2;
+      int oo=set[i].GetpFDeg();
+      if ((oo > op)
+          || ((oo == op) && (set[i].pLength > ol)))
+        en=i;
+      else
+        an=i;
+    }
+}
+
+
+// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
+int posInT_pLength(const TSet set,const int length,LObject &p)
+{
+  if (length==-1)
+    return 0;
+  if (set[length].length<p.length)
+    return length+1;
+
+  int i;
+  int an = 0;
+  int en= length;
+  int ol = p.GetpLength();
+
+  loop
+  {
+    if (an >= en-1)
+    {
+      if (set[an].pLength>ol) return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    if (set[i].pLength>ol) en=i;
+    else                        an=i;
+  }
+}
+
+#endif
+
+#endif // KUTIL_CC
Index: kernel/kutil.h
===================================================================
--- kernel/kutil.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/kutil.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,572 @@
+#ifndef KUTIL_H
+#define KUTIL_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: kutil.h,v 1.1.1.1 2003-10-06 12:15:52 Singular Exp $ */
+/*
+* ABSTRACT: kernel: utils for kStd
+*/
+
+
+#include <string.h>
+#include "mod2.h"
+#include <mylimits.h>
+
+#include "structs.h"
+#include "omalloc.h"
+#include "ring.h"
+#include "structs.h"
+#include "pShallowCopyDelete.h"
+
+#if 1
+#define setmax 16
+#define setmaxL 56
+#define setmaxLinc 32
+#define setmaxT 64
+#define setmaxTinc 32
+#else
+#define setmax 16
+#define setmaxL 16
+#define setmaxLinc 16
+#define setmaxT 16
+#define setmaxTinc 16
+#endif
+
+// define if you want std computations as in Singular version < 2
+// This disbales RedThrough, tailReductions against T (bba),
+// sets posInT = posInT15 (bba, strat->honey), and enables redFirst with LDeg
+// NOTE: the same effect can be achieved with option(oldStd)
+// #define HAVE_OLD_STD
+
+#ifdef HAVE_OLD_STD
+#define K_TEST_OPT_REDTHROUGH 0
+#define K_TEST_OPT_OLDSTD 1
+#else
+#define K_TEST_OPT_REDTHROUGH TEST_OPT_REDTHROUGH
+#define K_TEST_OPT_OLDSTD     TEST_OPT_OLDSTD
+#endif
+
+#undef NO_KINLINE
+#if !defined(KDEBUG) && !defined(NO_INLINE)
+#define KINLINE inline
+#else
+#define KINLINE
+#define NO_KINLINE 1
+#endif
+
+typedef int* intset;
+typedef class sTObject TObject;
+typedef class sLObject LObject;
+typedef TObject * TSet;
+typedef LObject * LSet;
+
+class sTObject
+{
+public:
+  poly p;       // Lm(p) \in currRing Tail(p) \in tailRing
+  poly t_p;     // t_p \in tailRing: as monomials Lm(t_p) == Lm(p)
+  ring tailRing;
+  poly max;     // p_GetMaxExpP(pNext(p))
+  long FDeg;    // pFDeg(p)
+  int ecart,
+    length,     // as of pLDeg
+    pLength,    // either == 0, or == pLength(p)
+    i_r;        // index of TObject in R set, or -1 if not in T
+  BOOLEAN is_normalized; // true, if pNorm was called on p, false otherwise
+
+  // initialization
+  KINLINE void Init(ring r = currRing);
+  KINLINE sTObject(ring tailRing = currRing);
+  KINLINE sTObject(poly p, ring tailRing = currRing);
+  KINLINE sTObject(poly p, ring c_r, ring tailRing);
+  KINLINE sTObject(sTObject* T, int copy);
+
+  KINLINE void Set(ring r=currRing);
+  KINLINE void Set(poly p_in, ring r=currRing);
+  KINLINE void Set(poly p_in, ring c_r, ring t_r);
+
+  // Frees the polys of T
+  KINLINE void Delete();
+  // Sets polys to NULL
+  KINLINE void Clear();
+  // makes a copy of the poly of T
+  KINLINE void Copy();
+
+  // ring-dependent Lm access: these might result in allocation of monomials
+  KINLINE poly GetLmCurrRing();
+  KINLINE poly GetLmTailRing();
+  KINLINE poly GetLm(ring r);
+  // this returns Lm and ring r (preferably from tailRing), but does not
+  // allocate a new poly
+  KINLINE void GetLm(poly &p, ring &r) const;
+  KINLINE BOOLEAN IsNull() const;
+
+  KINLINE int GetpLength();
+
+  // makes sure that T.p exists
+  KINLINE void SetLmCurrRing();
+
+  // Iterations
+  // simply get the next monomial
+  KINLINE poly Next();
+  KINLINE void LmDeleteAndIter();
+
+  // deg stuff
+  // computes pFDeg
+  KINLINE long pFDeg() const;
+  // computes and sets FDeg
+  KINLINE long SetpFDeg();
+  // gets stored FDeg
+  KINLINE long GetpFDeg() const;
+
+  // computes pLDeg
+  KINLINE long pLDeg();
+  // sets length, FDeg, returns LDeg
+  KINLINE long SetDegStuffReturnLDeg();
+
+  // arithmetic
+  KINLINE void Mult_nn(number n);
+  KINLINE void ShallowCopyDelete(ring new_tailRing, omBin new_tailBin,
+                                 pShallowCopyDeleteProc p_shallow_copy_delete,
+                                 BOOLEAN set_max = TRUE);
+  // manipulations
+  KINLINE void pNorm();
+  KINLINE void pCleardenom();
+
+#ifdef KDEBUG
+  void wrp();
+#endif
+};
+
+class sLObject : public sTObject
+{
+
+public:
+  unsigned long sev;
+  poly  p1,p2; /*- the pair p comes from -*/
+
+  poly  lcm;   /*- the lcm of p1,p2 -*/
+  poly last;   // pLast(p) during reductions
+  kBucket_pt bucket;
+  int   i_r1, i_r2;
+
+  // initialization
+  KINLINE void Init(ring tailRing = currRing);
+  KINLINE sLObject(ring tailRing = currRing);
+  KINLINE sLObject(poly p, ring tailRing = currRing);
+  KINLINE sLObject(poly p, ring c_r, ring tailRing);
+
+  // Frees the polys of L
+  KINLINE void Delete();
+  KINLINE void Clear();
+
+  // Iterations
+  KINLINE void LmDeleteAndIter();
+  KINLINE poly LmExtractAndIter();
+
+  // spoly related things
+  // preparation for reduction if not spoly
+  KINLINE void PrepareRed(BOOLEAN use_bucket);
+  KINLINE void SetLmTail(poly lm, poly new_p, int length,
+                         int use_bucket, ring r, poly last);
+  KINLINE void Tail_Minus_mm_Mult_qq(poly m, poly qq, int lq, poly spNoether);
+  KINLINE void Tail_Mult_nn(number n);
+  // deletes bucket, makes sure that p and t_p exists
+  KINLINE poly GetP(omBin lmBin = NULL);
+  // similar, except that only t_p exists
+  KINLINE poly GetTP();
+
+  // does not delete bucket, just canonicalizes it
+  // returned poly is such that Lm(p) \in currRing, Tail(p) \in tailRing
+  KINLINE poly CanonicalizeP();
+
+  // makes a copy of the poly of L
+  KINLINE void Copy();
+  // gets the poly and makes a copy of it
+  KINLINE poly CopyGetP();
+
+  KINLINE int GetpLength();
+  KINLINE long pLDeg(BOOLEAN use_last);
+  KINLINE long pLDeg();
+  KINLINE int SetLength(BOOLEAN lengt_pLength = FALSE);
+  KINLINE long SetDegStuffReturnLDeg();
+  KINLINE long SetDegStuffReturnLDeg(BOOLEAN use_last);
+
+  // returns minimal component of p
+  KINLINE long MinComp();
+  // returns component of p
+  KINLINE long Comp();
+
+  KINLINE void ShallowCopyDelete(ring new_tailRing,
+                                 pShallowCopyDeleteProc p_shallow_copy_delete);
+
+  // sets sev
+  KINLINE void SetShortExpVector();
+
+  // enable assignment from TObject
+  KINLINE sLObject& operator=(const sTObject&);
+
+  // get T's corresponding to p1, p2: they might return NULL
+  KINLINE TObject* T_1(const skStrategy* strat);
+  KINLINE TObject* T_2(const skStrategy* strat);
+  KINLINE void     T_1_2(const skStrategy* strat,
+                         TObject* &T_1, TObject* &T_2);
+};
+
+
+extern int HCord;
+
+class skStrategy;
+typedef skStrategy * kStrategy;
+class skStrategy
+{
+public:
+  kStrategy next;
+  int (*red)(LObject * L,kStrategy strat);
+  void (*initEcart)(LObject * L);
+  int (*posInT)(const TSet T,const int tl,LObject &h);
+  int (*posInL)(const LSet set, const int length,
+                LObject* L,const kStrategy strat);
+  void (*enterS)(LObject h, int pos,kStrategy strat, int atR = -1);
+  void (*initEcartPair)(LObject * h, poly f, poly g, int ecartF, int ecartG);
+  int (*posInLOld)(const LSet Ls,const int Ll,
+                   LObject* Lo,const kStrategy strat);
+  pFDegProc pOrigFDeg;
+  pLDegProc pOrigLDeg;
+  pFDegProc pOrigFDeg_TailRing;
+  pLDegProc pOrigLDeg_TailRing;
+
+  LObject P;
+  ideal Shdl;
+  ideal D; /*V(S) is in D(D)*/
+  ideal M; /*set of minimal generators*/
+  polyset S;
+  intset ecartS;
+  intset lenS;
+  intset lenSw; /* for tgb.ccc */
+  intset fromQ;
+  unsigned long* sevS;
+  unsigned long* sevT;
+  TSet T;
+  LSet L;
+  LSet    B;
+  poly    kHEdge;
+  poly    kNoether;
+  poly    t_kHEdge; // same polys in tailring
+  KINLINE poly    kNoetherTail();
+  poly    t_kNoether;
+  BOOLEAN * NotUsedAxis;
+  poly tail;
+  leftv kIdeal;
+  intvec * kModW;
+  intvec * kHomW;
+  // procedure for ShalloCopy from tailRing  to currRing
+  pShallowCopyDeleteProc p_shallow_copy_delete;
+  // pointers to Tobjects R[i] is ith Tobject which is generated
+  TObject**  R;
+  // S_2_R[i] yields Tobject which corresponds to S[i]
+  int*      S_2_R;
+  ring tailRing;
+  omBin lmBin;
+  omBin tailBin;
+  int cp,c3;
+  int sl,mu;
+  int tl,tmax;
+  int Ll,Lmax;
+  int Bl,Bmax;
+  int ak,LazyDegree,LazyPass;
+  int syzComp;
+  int HCord;
+  int lastAxis;
+  int newIdeal;
+  int minim;
+  BOOLEAN interpt;
+  BOOLEAN homog;
+  BOOLEAN kHEdgeFound;
+  BOOLEAN honey,sugarCrit;
+  BOOLEAN Gebauer,noTailReduction;
+  BOOLEAN fromT;
+  BOOLEAN noetherSet;
+  BOOLEAN update;
+  BOOLEAN posInLOldFlag;
+  BOOLEAN use_buckets;
+  BOOLEAN interred_flag;
+  BOOLEAN *pairtest;/*used for enterOnePair*/
+  // if set, pLDeg(p, l) == (pFDeg(pLast(p), pLength)
+  BOOLEAN LDegLast;
+  // if set, then L.length == L.pLength
+  BOOLEAN length_pLength;
+  // if set, then posInL does not depend on L.length
+  BOOLEAN posInLDependsOnLength;
+  /*FALSE, if posInL == posInL10*/
+  char    redTailChange;
+  char    news;
+  char    newt;/*used for messageSets*/
+
+  skStrategy();
+  ~skStrategy();
+
+  // return TObject corresponding to S[i]: assume that it exists
+  // i.e. no error checking is done
+  KINLINE TObject* S_2_T(int i);
+  // like S_2_T, except that NULL is returned if it can not be found
+  KINLINE TObject* s_2_t(int i);
+};
+
+void deleteHC(poly *p, int *e, int *l, kStrategy strat);
+void deleteHC(LObject* L, kStrategy strat, BOOLEAN fromNext = FALSE);
+void deleteInS (int i,kStrategy strat);
+void cleanT (kStrategy strat);
+LSet initL ();
+void deleteInL(LSet set, int *length, int j,kStrategy strat);
+void enterL (LSet *set,int *length, int *LSetmax, LObject p,int at);
+void enterSBba (LObject p,int atS,kStrategy strat, int atR = -1);
+void initEcartPairBba (LObject* Lp,poly f,poly g,int ecartF,int ecartG);
+void initEcartPairMora (LObject* Lp,poly f,poly g,int ecartF,int ecartG);
+int posInS (kStrategy strat,int length,poly p, int ecart_p);
+int posInT0 (const TSet set,const int length,LObject &p);
+int posInT1 (const TSet set,const int length,LObject &p);
+int posInT2 (const TSet set,const int length,LObject &p);
+int posInT11 (const TSet set,const int length,LObject &p);
+int posInT110 (const TSet set,const int length,LObject &p);
+int posInT13 (const TSet set,const int length,LObject &p);
+int posInT15 (const TSet set,const int length,LObject &p);
+int posInT17 (const TSet set,const int length,LObject &p);
+int posInT19 (const TSet set,const int length,LObject &p);
+int posInT_EcartpLength(const TSet set,const int length,LObject &p);
+
+#ifdef HAVE_MORE_POS_IN_T
+int posInT_EcartFDegpLength(const TSet set,const int length,LObject &p);
+int posInT_FDegpLength(const TSet set,const int length,LObject &p);
+int posInT_pLength(const TSet set,const int length,LObject &p);
+#endif
+
+
+void reorderS (int* suc,kStrategy strat);
+int posInL0 (const LSet set, const int length,
+             LObject* L,const kStrategy strat);
+int posInL11 (const LSet set, const int length,
+             LObject* L,const kStrategy strat);
+int posInL13 (const LSet set, const int length,
+             LObject* L,const kStrategy strat);
+int posInL15 (const LSet set, const int length,
+             LObject* L,const kStrategy strat);
+int posInL17 (const LSet set, const int length,
+             LObject* L,const kStrategy strat);
+int posInL10 (const LSet set, const int length,
+             LObject* L,const kStrategy strat);
+KINLINE poly redtailBba (poly p,int pos,kStrategy strat);
+poly redtailBba (LObject *L, int pos,kStrategy strat, BOOLEAN withT = FALSE);
+poly redtailBba (TObject *T, int pos,kStrategy strat, BOOLEAN withT = FALSE);
+poly redtail (poly p,int pos,kStrategy strat);
+poly redtail (LObject *L,int pos,kStrategy strat);
+poly redNF (poly h,kStrategy strat);
+int redNF0 (LObject *P,kStrategy strat);
+poly redNFTail (poly h,const int sl,kStrategy strat);
+int redHoney (LObject* h, kStrategy strat);
+int redLazy (LObject* h,kStrategy strat);
+int redHomog (LObject* h,kStrategy strat);
+void enterpairs (poly h, int k, int ec, int pos,kStrategy strat, int atR = -1);
+void entersets (LObject h);
+void pairs ();
+void message (int i,int* reduc,int* olddeg,kStrategy strat,int red_result);
+void messageStat (int srmax,int lrmax,int hilbcount,kStrategy strat);
+#ifdef KDEBUG
+void messageSets (kStrategy strat);
+#else
+#define messageSets(s)  ((void) 0)
+#endif
+
+void initEcartNormal (LObject* h);
+void initEcartBBA (LObject* h);
+void initS (ideal F, ideal Q,kStrategy strat);
+void initSL (ideal F, ideal Q,kStrategy strat);
+void updateS(BOOLEAN toT,kStrategy strat);
+void enterT (LObject p,kStrategy strat, int atT = -1);
+void cancelunit (LObject* p);
+void HEckeTest (poly pp,kStrategy strat);
+void initBuchMoraCrit(kStrategy strat);
+void initHilbCrit(ideal F, ideal Q, intvec **hilb,kStrategy strat);
+void initBuchMoraPos(kStrategy strat);
+void initBuchMora (ideal F, ideal Q,kStrategy strat);
+void exitBuchMora (kStrategy strat);
+void updateResult(ideal r,ideal Q,kStrategy strat);
+void completeReduce (kStrategy strat);
+void kFreeStrat(kStrategy strat);
+BOOLEAN homogTest(polyset F, int Fmax);
+BOOLEAN newHEdge(polyset S, kStrategy strat);
+// returns index of p in TSet, or -1 if not found
+int kFindInT(poly p, TSet T, int tlength);
+
+// return -1 if no divisor is found
+//        number of first divisor, otherwise
+int kFindDivisibleByInT(const TSet &T, const unsigned long* sevT,
+                        const int tl, const LObject* L, const int start=0);
+// same with S
+int kFindDivisibleByInS(const polyset &S, const unsigned long* sev,
+                        const int sl, LObject* L);
+
+TObject*
+kFindDivisibleByInS(kStrategy strat, int pos, LObject* L, TObject *T,
+                    long ecart = LONG_MAX);
+
+
+/***************************************************************
+ *
+ * stuff to be inlined
+ *
+ ***************************************************************/
+
+KINLINE TSet initT ();
+KINLINE TObject** initR();
+KINLINE unsigned long* initsevT();
+KINLINE poly k_LmInit_currRing_2_tailRing(poly p, ring tailRing, omBin bin);
+KINLINE poly k_LmInit_tailRing_2_currRing(poly p, ring tailRing, omBin bin);
+KINLINE poly k_LmShallowCopyDelete_currRing_2_tailRing(poly p, ring tailRing, omBin bin);
+KINLINE poly k_LmShallowCopyDelete_tailRing_2_currRing(poly p, ring tailRing,  omBin bin);
+
+KINLINE poly k_LmInit_currRing_2_tailRing(poly p, ring tailRing);
+KINLINE poly k_LmInit_tailRing_2_currRing(poly p, ring tailRing);
+KINLINE poly k_LmShallowCopyDelete_currRing_2_tailRing(poly p, ring tailRing);
+KINLINE poly k_LmShallowCopyDelete_tailRing_2_currRing(poly p, ring tailRing);
+
+// if exp bound is not violated, return TRUE and
+//                               get m1 = LCM(LM(p1), LM(p2))/LM(p1)
+//                                   m2 = LCM(LM(p1), LM(p2))/LM(p2)
+// return FALSE and m1 == NULL, m2 == NULL     , otherwise
+KINLINE BOOLEAN k_GetLeadTerms(const poly p1, const poly p2, const ring p_r,
+                               poly &m1, poly &m2, const ring m_r);
+#ifdef KDEBUG
+// test strat
+BOOLEAN kTest(kStrategy strat);
+// test strat, and test that S is contained in T
+BOOLEAN kTest_TS(kStrategy strat);
+// test LObject
+BOOLEAN kTest_L(LObject* L, ring tailRing = NULL,
+                 BOOLEAN testp = FALSE, int lpos = -1,
+                 TSet T = NULL, int tlength = -1);
+// test TObject
+BOOLEAN kTest_T(TObject* T, ring tailRing = NULL, int tpos = -1, char TN = '?');
+// test set strat->SevS
+BOOLEAN kTest_S(kStrategy strat);
+#else
+#define kTest(A)        ((void)0)
+#define kTest_TS(A)     ((void)0)
+#define kTest_T(T)      ((void)0)
+#define kTest_S(T)      ((void)0)
+#define kTest_L(T)      ((void)0)
+#endif
+
+
+/***************************************************************
+ *
+ * From kstd2.cc
+ *
+ ***************************************************************/
+ideal bba (ideal F, ideal Q,intvec *w,intvec *hilb,kStrategy strat);
+poly kNF2 (ideal F, ideal Q, poly q, kStrategy strat, int lazyReduce);
+ideal kNF2 (ideal F,ideal Q,ideal q, kStrategy strat, int lazyReduce);
+void initBba(ideal F,kStrategy strat);
+
+/***************************************************************
+ *
+ * From kSpolys.cc
+ *
+ ***************************************************************/
+// Reduces PR with PW
+// Assumes PR != NULL, PW != NULL, Lm(PW) divides Lm(PR)
+// Changes: PR
+// Const:   PW
+// If coef != NULL, then *coef is a/gcd(a,b), where a = LC(PR), b = LC(PW)
+// If strat != NULL, tailRing is changed if reduction would violate exp bound
+// of tailRing
+// Returns: 0 everything ok, no tailRing change
+//          1 tailRing has successfully changed (strat != NULL)
+//          2 no reduction performed, tailRing needs to be changed first
+//            (strat == NULL)
+//         -1 tailRing change could not be performed due to exceeding exp
+//            bound of currRing
+int ksReducePoly(LObject* PR,
+                 TObject* PW,
+                 poly spNoether = NULL,
+                 number *coef = NULL,
+                 kStrategy strat = NULL);
+
+// Reduces PR at Current->next with PW
+// Assumes PR != NULL, Current contained in PR
+//         Current->next != NULL, LM(PW) devides LM(Current->next)
+// Changes: PR
+// Const:   PW
+// Return: see ksReducePoly
+int ksReducePolyTail(LObject* PR,
+                     TObject* PW,
+                     poly Current,
+                     poly spNoether = NULL);
+
+KINLINE int ksReducePolyTail(LObject* PR, TObject* PW, LObject* Red);
+
+// Creates S-Poly of Pair
+// Const:   Pair->p1, Pair->p2
+// Changes: Pair->p == S-Poly of p1, p2
+// Assume:  Pair->p1 != NULL && Pair->p2
+void ksCreateSpoly(LObject* Pair, poly spNoether = NULL,
+                   int use_buckets=0, ring tailRing=currRing,
+                   poly m1 = NULL, poly m2 = NULL, TObject** R = NULL);
+
+/*2
+* creates the leading term of the S-polynomial of p1 and p2
+* do not destroy p1 and p2
+* remarks:
+*   1. the coefficient is 0 (nNew)
+*   2. pNext is undefined
+*/
+poly ksCreateShortSpoly(poly p1, poly p2, ring tailRing);
+
+
+/*
+* input - output: a, b
+* returns:
+*   a := a/gcd(a,b), b := b/gcd(a,b)
+*   and return value
+*       0  ->  a != 1,  b != 1
+*       1  ->  a == 1,  b != 1
+*       2  ->  a != 1,  b == 1
+*       3  ->  a == 1,  b == 1
+*   this value is used to control the spolys
+*/
+int ksCheckCoeff(number *a, number *b);
+
+// old stuff
+KINLINE poly ksOldSpolyRed(poly p1, poly p2, poly spNoether = NULL);
+KINLINE poly ksOldSpolyRedNew(poly p1, poly p2, poly spNoether = NULL);
+KINLINE poly ksOldCreateSpoly(poly p1, poly p2, poly spNoether = NULL, ring r = currRing);
+KINLINE void ksOldSpolyTail(poly p1, poly q, poly q2, poly spNoether, ring r = currRing);
+
+/***************************************************************
+ *
+ * Routines related for ring changes during std computations
+ *
+ ***************************************************************/
+// return TRUE and set m1, m2 to k_GetLcmTerms,
+//             if spoly creation of strat->P does not violate
+//             exponent bound of strat->tailRing
+//      FALSE, otherwise
+BOOLEAN kCheckSpolyCreation(LObject* L, kStrategy strat, poly &m1, poly &m2);
+// change strat->tailRing and adjust all data in strat, L, and T:
+// new tailRing has larger exponent bound
+// do nothing and return FALSE if exponent bound increase would result in
+// larger exponent bound that that of currRing
+BOOLEAN kStratChangeTailRing(kStrategy strat,
+                             LObject* L = NULL, TObject* T = NULL,
+                             // take this as new_expbound: if 0
+                             // new expbound is 2*expbound of tailRing
+                             unsigned long new_expbound = 0);
+// initiate a change of the tailRing of strat -- should be called
+// right before main loop in bba
+void kStratInitChangeTailRing(kStrategy strat);
+
+#include "kInline.cc"
+
+
+#endif
Index: kernel/longalg.cc
===================================================================
--- kernel/longalg.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/longalg.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,2860 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: longalg.cc,v 1.1.1.1 2003-10-06 12:15:54 Singular Exp $ */
+/*
+* ABSTRACT:   algebraic numbers
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "mod2.h"
+#include "structs.h"
+#include "omalloc.h"
+#include "febase.h"
+#include "longrat.h"
+#include "modulop.h"
+#include "numbers.h"
+#include "polys.h"
+#include "ideals.h"
+#include "ring.h"
+#ifdef HAVE_FACTORY
+#include "clapsing.h"
+#endif
+#include "longalg.h"
+
+naIdeal naI=NULL;
+
+napoly naMinimalPoly;
+int naNumbOfPar;
+#ifndef LONGALGNEW
+int napMonomSize;
+char **naParNames;
+#else /* LONGALGNEW */
+#define naParNames (currRing->parameter)
+#define napNormalize(p) p_Normalize(p,nacRing)
+#endif /* LONGALGNEW */
+static int naIsChar0;
+static int naPrimeM;
+
+#ifdef LDEBUG
+#define naTest(a) naDBTest(a,__FILE__,__LINE__)
+BOOLEAN naDBTest(number a, char *f,int l);
+#else
+#define naTest(a)
+#endif
+
+number (*naMap)(number from);
+/* procedure variables */
+static numberfunc
+                nacMult, nacSub, nacAdd, nacDiv, nacIntDiv;
+static number   (*nacGcd)(number a, number b, const ring r);
+static number   (*nacLcm)(number a, number b, const ring r);
+static void     (*nacDelete)(number *a, const ring r);
+       number   (*nacInit)(int i);
+static int      (*nacInt)(number &n);
+       void     (*nacNormalize)(number &a);
+static number   (*nacNeg)(number a);
+static void     (*nacWrite)(number &a);
+       number   (*nacCopy)(number a);
+static number   (*nacInvers)(number a);
+       BOOLEAN  (*nacIsZero)(number a);
+static BOOLEAN  (*nacIsOne)(number a);
+static BOOLEAN  (*nacIsMOne)(number a);
+static BOOLEAN  (*nacGreaterZero)(number a);
+static char   * (*nacRead) (char *s, number *a);
+#ifndef LONGALGNEW
+extern void     napDelete(napoly *p);
+#endif /* not LONGALGNEW */
+static napoly napRedp(napoly q);
+static napoly napTailred(napoly q);
+static BOOLEAN napDivPoly(napoly p, napoly q);
+static int napExpi(int i, napoly a, napoly b);
+static ring nacRing;
+
+static number nadGcd( number a, number b, const ring r) { return nacInit(1); }
+/*2
+*  sets the appropriate operators
+*/
+void naSetChar(int i, ring r)
+{
+  if (naI!=NULL)
+  {
+    int j;
+    for (j=naI->anz-1; j>=0; j--)
+       napDelete (&naI->liste[j]);
+    omFreeSize((ADDRESS)naI->liste,naI->anz*sizeof(napoly));
+    omFreeBin((ADDRESS)naI, snaIdeal_bin);
+    naI=NULL;
+  }
+  naMap = naCopy;
+  /*------------ set naMinimalPoly -----------------------------------*/
+  if (r->minpoly!=NULL)
+    naMinimalPoly=((lnumber)r->minpoly)->z;
+  else
+    naMinimalPoly = NULL;
+  naNumbOfPar=rPar(r);
+#ifndef LONGALGNEW
+  naParNames=r->parameter;
+  napMonomSize = RECA_SIZE + naNumbOfPar*SIZEOF_PARAMETER;
+#endif /* not LONGALGNEW */
+  if (i == 1)
+  {
+    naIsChar0 = 1;
+  }
+  else if (i < 0)
+  {
+    naIsChar0 = 0;
+    npSetChar(-i, r->algring); // to be changed HS
+  }
+#ifdef TEST
+  else
+  {
+    Print("naSetChar:c=%d param=%d\n",i,rPar(r));
+  }
+#endif
+  nacRing        = r->algring;
+  nacInit        = nacRing->cf->nInit;
+  nacInt         = nacRing->cf->nInt;
+  nacCopy        = nacRing->cf->nCopy;
+  nacAdd         = nacRing->cf->nAdd;
+  nacSub         = nacRing->cf->nSub;
+  nacNormalize   = nacRing->cf->nNormalize;
+  nacNeg         = nacRing->cf->nNeg;
+  nacIsZero      = nacRing->cf->nIsZero;
+  nacRead        = nacRing->cf->nRead;
+  nacWrite       = nacRing->cf->nWrite;
+  nacGreaterZero = nacRing->cf->nGreaterZero;
+  nacIsOne       = nacRing->cf->nIsOne;
+  nacIsMOne      = nacRing->cf->nIsMOne;
+  nacGcd         = nacRing->cf->nGcd;
+  nacLcm         = nacRing->cf->nLcm;
+  nacDelete      = nacRing->cf->cfDelete;
+  nacMult        = nacRing->cf->nMult;
+  nacDiv         = nacRing->cf->nDiv;
+  nacIntDiv      = nacRing->cf->nIntDiv;
+  nacInvers      = nacRing->cf->nInvers;
+}
+
+/*============= procedure for polynomials: napXXXX =======================*/
+
+
+
+#ifdef LDEBUG
+static void napTest(napoly p)
+{
+  while (p != NULL)
+  {
+    if (naIsChar0)
+      nlDBTest(napGetCoeff(p), "", 0);
+    napIter(p);
+  }
+}
+#else
+#define napTest(p) ((void) 0)
+#endif
+
+#ifndef LONGALGNEW
+/*3
+* creates  an napoly poly
+*/
+static napoly napInit(int i)
+{
+  napoly a = (napoly)omAlloc0(napMonomSize);
+
+  a->ko = nacInit(i);
+  if (!nacIsZero(a->ko))
+  {
+    return a;
+  }
+  else
+  {
+    omFreeSize((ADDRESS)a, napMonomSize);
+    return NULL;
+  }
+}
+#define napMultCopy(p,q)  napMult(napCopy(p),napCopy(q))
+#define napIsConstant(p)  (napDeg(p)==0)
+#define napSetCoeff(p,n) {nacDelete(&((p)->ko),nacRing);(p)->ko=n;}
+#else /* LONGALGNEW */
+#define napInit(i)       (napoly)p_ISet(i,nacRing)
+#define napSetCoeff(p,n) {nacDelete(&napGetCoeff(p),nacRing);napGetCoeff(p)=n;}
+#define napDelete1(p)    p_LmDelete((poly *)p, nacRing)
+#define napCopy(p)       (napoly)p_Copy((poly)p,nacRing)
+#define nap_Copy(p,r)       (napoly)p_Copy((poly)p,r->algring)
+#define napComp(p,q)     p_LmCmp((poly)p,(poly)q, nacRing)
+#define napMultT(A,E)    A=(napoly)p_Mult_mm((poly)A,(poly)E,nacRing)
+#define napMult(A,B)     (napoly)p_Mult_q((poly)A,(poly)B,nacRing)
+#define napMultCopy(A,B)   (napoly)pp_Mult_qq((poly)A,(poly)B,nacRing)
+#define napIsConstant(p) p_LmIsConstant(p,nacRing)
+#define napDeg(p)        (int)p_ExpVectorQuerSum(p, nacRing)
+#endif /* LONGALGNEW */
+
+/*3
+* creates  an napoly
+*/
+napoly napInitz(number z)
+{
+#ifndef LONGALGNEW
+  napoly a = (napoly)omAlloc0(napMonomSize);
+#else /* LONGALGNEW */
+  napoly a = (napoly)p_Init(nacRing);
+#endif /* LONGALGNEW */
+  napGetCoeff(a) = z;
+  return a;
+}
+
+#ifndef LONGALGNEW
+/*3
+*  deletes head of  an napoly poly
+*/
+static void napDelete1(napoly *p)
+{
+  napoly h = *p;
+
+  if (h!=NULL)
+  {
+    *p = h->ne;
+    nacDelete(&(h->ko),nacRing);
+    omFreeSize((ADDRESS)h, napMonomSize);
+  }
+}
+
+/*3
+*  delete an napoly poly
+*/
+void napDelete(napoly *p)
+{
+  napoly w, h = *p;
+
+  while (h!=NULL)
+  {
+    w = h;
+    h = h->ne;
+    nacDelete(&(w->ko),nacRing);
+    omFreeSize((ADDRESS)w, napMonomSize);
+  }
+  *p = NULL;
+}
+
+void nap_Delete(napoly *p, const ring r)
+{
+  napoly w, h = *p;
+
+  while (h!=NULL)
+  {
+    w = h;
+    h = h->ne;
+    n_Delete(&(w->ko),r->algring);
+    omFree((ADDRESS)w);
+  }
+  *p = NULL;
+}
+
+
+/*3
+* copy a napoly. poly
+*/
+static napoly napCopy(napoly p)
+{
+  if (p==NULL) return NULL;
+
+  napoly w, a;
+
+  omCheckAddrSize(p,napMonomSize);
+  a = w = (napoly)omAlloc(napMonomSize);
+  memcpy4(w->e, p->e, naNumbOfPar * SIZEOF_PARAMETER);
+  w->ko = nacCopy(p->ko);
+  loop
+  {
+    p=p->ne;
+    if (p==NULL) break;
+    omCheckAddrSize(p,napMonomSize);
+    a->ne = (napoly)omAlloc(napMonomSize);
+    a = a->ne;
+    memcpy4(a->e, p->e, naNumbOfPar * SIZEOF_PARAMETER);
+    a->ko = nacCopy(p->ko);
+  }
+  a->ne = NULL;
+  return w;
+}
+#endif /* not LONGALGNEW */
+
+/*3
+* copy a napoly. poly
+*/
+static napoly napCopyNeg(napoly p)
+{
+#ifndef LONGALGNEW
+  napoly w, a;
+
+  if (p==NULL) return NULL;
+  omCheckAddrSize(p,napMonomSize);
+  a = w = (napoly)omAlloc(napMonomSize);
+  memcpy4(w->e, p->e, naNumbOfPar * SIZEOF_PARAMETER);
+  w->ko = nacNeg(nacCopy(p->ko));
+  loop
+  {
+    p=p->ne;
+    if (p==NULL) break;
+    omCheckAddrSize(p,napMonomSize);
+    a->ne = (napoly)omAlloc(napMonomSize);
+    a = a->ne;
+    memcpy4(a->e, p->e, naNumbOfPar * SIZEOF_PARAMETER);
+    a->ko = nacNeg(nacCopy(p->ko));
+  }
+  a->ne = NULL;
+  return w;
+#else /* LONGALGNEW */
+  napoly r=napCopy(p);
+  r=(napoly)p_Neg((poly)r, nacRing);
+  return r;
+#endif /* LONGALGNEW */
+}
+
+#ifndef LONGALGNEW
+/*3
+* Compare exponents of p and q
+*/
+static int  napComp(napoly p, napoly q)
+{
+  int  i = 0;
+
+  omCheckAddrSize(p,napMonomSize);
+  omCheckAddrSize(q,napMonomSize);
+  while (p->e[i] == q->e[i])
+  {
+    i++;
+    if (i >= naNumbOfPar)
+      return 0;
+  }
+  if (p->e[i]  >  q->e[i])
+    return 1;
+  else
+    return - 1;
+}
+
+/*3
+*  addition of napoly. polys
+*/
+napoly napAdd(napoly p1, napoly p2)
+{
+  napoly a1, p, a2, a;
+  int  c;  number t;
+
+  if (p1==NULL) return p2;
+  if (p2==NULL) return p1;
+  omCheckAddrSize(p1,napMonomSize);
+  omCheckAddrSize(p2,napMonomSize);
+  a1 = p1;
+  a2 = p2;
+  a = p  = (napoly)omAlloc(napMonomSize);
+  loop
+  {
+    c = napComp(a1, a2);
+    if (c == 1)
+    {
+      a = a->ne = a1;
+      a1 = a1->ne;
+      if (a1==NULL)
+      {
+        a->ne= a2;
+        break;
+      }
+      omCheckAddrSize(a1,napMonomSize);
+    }
+    else if (c == -1)
+    {
+      a = a->ne = a2;
+      a2 = a2->ne;
+      if (a2==NULL)
+      {
+        a->ne = a1;
+        break;
+      }
+      omCheckAddrSize(a2,napMonomSize);
+    }
+    else
+    {
+      t = nacAdd(a1->ko, a2->ko);
+      napDelete1(&a2);
+      if (nacIsZero(t))
+      {
+        nacDelete(&t,nacRing);
+        napDelete1(&a1);
+      }
+      else
+      {
+        nacDelete(&(a1->ko),nacRing);
+        a1->ko = t;
+        a = a->ne = a1;
+        a1 = a1->ne;
+      }
+      if (a1==NULL)
+      {
+        a->ne = a2;
+        break;
+      }
+      else if (a2==NULL)
+      {
+        a->ne = a1;
+        break;
+      }
+      omCheckAddrSize(a1,napMonomSize);
+      omCheckAddrSize(a2,napMonomSize);
+    }
+  }
+  a = p->ne;
+  omFreeSize((ADDRESS)p, napMonomSize);
+  return a;
+}
+
+
+/*3
+* multiply a napoly. poly by -1
+*/
+napoly napNeg(napoly a)
+{
+  napoly p = a;
+
+  while (p!=NULL)
+  {
+    omCheckAddrSize(p,napMonomSize);
+    p->ko = nacNeg(p->ko);
+    p = p->ne;
+  }
+  return a;
+}
+#endif /* not LONGALGNEW */
+
+/*3
+* returns ph * z
+*/
+static void napMultN(napoly p, number z)
+{
+  number t;
+
+  while (p!=NULL)
+  {
+    t = nacMult(napGetCoeff(p), z);
+    nacNormalize(t);
+    nacDelete(&napGetCoeff(p),nacRing);
+    napGetCoeff(p) = t;
+    napIter(p);
+  }
+}
+
+#ifndef LONGALGNEW
+/*3
+* update the polynomial a by multipying it by
+* the (number) coefficient
+* and the exponent vector (of) exp (a well initialized polynomial)
+*/
+static void napMultT(napoly a, napoly exp)
+{
+  int  i;
+  number t, h;
+  if (a==NULL)
+    return;
+  h = exp->ko;
+  if (nacIsOne(h))
+  {
+    do
+    {
+      for (i = naNumbOfPar - 1; i >= 0; i--)
+        a->e[i] += exp->e[i];
+      a = a->ne;
+    }
+    while (a!=NULL);
+  }
+  else
+  {
+    h = nacNeg(h);
+    if (nacIsOne(h))
+    {
+      h = nacNeg(h);
+      do
+      {
+        a->ko = nacNeg(a->ko);
+        for (i = naNumbOfPar - 1; i >= 0; i--)
+          a->e[i] += exp->e[i];
+        a = a->ne;
+      }
+      while (a!=NULL);
+    }
+    else
+    {
+      h = nacNeg(h);
+      do
+      {
+        t = nacMult(a->ko, h);
+        nacDelete(&(a->ko),nacRing);
+        a->ko = t;
+        for (i = naNumbOfPar - 1; i >= 0; i--)
+          a->e[i] += exp->e[i];
+        a = a->ne;
+      }
+      while (a!=NULL);
+    }
+    // need to do this, since nacNeg might have changed h
+    exp->ko = h;
+  }
+}
+#endif /* LONGALGNEW */
+
+#ifndef LONGALGNEW
+/*3
+* multiplication of napoly. polys
+* multiply p1 with p2, p1 and p2 are destroyed
+*/
+static napoly napMult(napoly p1, napoly p2)
+{
+  napoly a1, a2, b, h;
+  if (p1==NULL)
+  {
+    napDelete(&p2);
+    return NULL;
+  }
+  if (p2==NULL)
+  {
+    napDelete(&p1);
+    return NULL;
+  }
+  b = NULL;
+  a1 = p1;
+  a2 = p2;
+  if (a2->ne!=NULL)
+  {
+    if (a1->ne!=NULL)
+    {
+      do
+      {
+        a1 = a1->ne;
+        a2 = a2->ne;
+      }
+      while ((a1!=NULL) && (a2!=NULL));
+      if (a1!=NULL)
+      {
+        a1 = p1;
+        a2 = p2;
+      }
+      else
+      {
+        a1 = p2;
+        a2 = p1;
+      }
+      do
+      {
+        if (a2->ne!=NULL)
+          h = napCopy(a1);
+        else
+          h = a1;
+        napMultT(h, a2);
+        b = napAdd(h, b);
+        napDelete1(&a2);
+      }
+      while (a2!=NULL);
+    }
+    else
+    {
+      napMultT(a2, a1);
+      b = napAdd(a2, b);
+      napDelete1(&a1);
+    }
+  }
+  else
+  {
+    napMultT(a1, a2);
+    b = napAdd(a1, b);
+    napDelete1(&a2);
+  }
+  return b;
+}
+#endif /* not LONGALGNEW */
+
+/*3
+*  division with rest; f = g*q + r, returns r and destroy f
+*/
+static napoly napRemainder(napoly f, const napoly  g)
+{
+  napoly a, h, qq;
+
+#ifndef LONGALGNEW
+  qq = (napoly)omAlloc(napMonomSize);
+#else /* LONGALGNEW */
+  qq = (napoly)p_Init(nacRing);
+#endif /* LONGALGNEW */
+  napNext(qq) = NULL;
+  napNormalize(g);
+  napNormalize(f);
+  a = f;
+  do
+  {
+    napSetExp(qq,1, napGetExp(a,1) - napGetExp(g,1));
+    p_Setm(qq,nacRing);
+    napGetCoeff(qq) = nacDiv(napGetCoeff(a), napGetCoeff(g));
+    napGetCoeff(qq) = nacNeg(napGetCoeff(qq));
+    nacNormalize(napGetCoeff(qq));
+    h = napCopy(g);
+    napMultT(h, qq);
+    napNormalize(h);
+    nacDelete(&napGetCoeff(qq),nacRing);
+    a = napAdd(a, h);
+  }
+  while ((a!=NULL) && (napGetExp(a,1) >= napGetExp(g,1)));
+#ifndef LONGALGNEW
+  omFreeSize((ADDRESS)qq, napMonomSize);
+#else /* LONGALGNEW */
+  omFreeBinAddr(qq);
+#endif /* LONGALGNEW */
+  return a;
+}
+
+/*3
+*  division with rest; f = g*q + r,  destroy f
+*/
+static void napDivMod(napoly f, napoly  g, napoly *q, napoly *r)
+{
+  napoly a, h, b, qq;
+
+#ifndef LONGALGNEW
+  qq = (napoly)omAlloc(napMonomSize);
+#else /* LONGALGNEW */
+  qq = (napoly)p_Init(nacRing);
+#endif /* LONGALGNEW */
+  napNext(qq) = b = NULL;
+  napNormalize(g);
+  napNormalize(f);
+  a = f;
+  do
+  {
+    napSetExp(qq,1, napGetExp(a,1) - napGetExp(g,1));
+    p_Setm(qq,nacRing);
+    napGetCoeff(qq) = nacDiv(napGetCoeff(a), napGetCoeff(g));
+    nacNormalize(napGetCoeff(qq));
+    b = napAdd(b, napCopy(qq));
+    napGetCoeff(qq) = nacNeg(napGetCoeff(qq));
+    h = napCopy(g);
+    napMultT(h, qq);
+    napNormalize(h);
+    nacDelete(&napGetCoeff(qq),nacRing);
+    a = napAdd(a, h);
+  }
+  while ((a!=NULL) && (napGetExp(a,1) >= napGetExp(g,1)));
+#ifndef LONGALGNEW
+  omFreeSize((ADDRESS)qq, napMonomSize);
+#else /* LONGALGNEW */
+  omFreeBinAddr(qq);
+#endif /* LONGALGNEW */
+  *q = b;
+  *r = a;
+}
+
+/*3
+*  returns z with z*x mod c = 1
+*/
+static napoly napInvers(napoly x, const napoly c)
+{
+  napoly y, r, qa, qn, q;
+  number t, h;
+
+  if (napGetExp(x,1) >= napGetExp(c,1))
+    x = napRemainder(x, c);
+  if (x==NULL)
+  {
+    goto zero_divisor;
+  }
+  if (napGetExp(x,1)==0)
+  {
+    if (!nacIsOne(napGetCoeff(x)))
+    {
+      nacNormalize(napGetCoeff(x));
+      t = nacInvers(napGetCoeff(x));
+      nacNormalize(t);
+      nacDelete(&napGetCoeff(x),nacRing);
+      napGetCoeff(x) = t;
+    }
+    return x;
+  }
+  y = napCopy(c);
+  napDivMod(y, x, &qa, &r);
+  if (r==NULL)
+  {
+    goto zero_divisor;
+  }
+  if (napGetExp(r,1)==0)
+  {
+    nacNormalize(napGetCoeff(r));
+    t = nacInvers(napGetCoeff(r));
+    nacNormalize(t);
+    t = nacNeg(t);
+    napMultN(qa, t);
+    nacDelete(&t,nacRing);
+    napNormalize(qa);
+    napDelete(&x);
+    napDelete(&r);
+    return qa;
+  }
+  y = x;
+  x = r;
+  napDivMod(y, x, &q, &r);
+  if (r==NULL)
+  {
+    goto zero_divisor;
+  }
+  if (napGetExp(r,1)==0)
+  {
+    q = napMult(q, qa);
+    q = napAdd(q, napInit(1));
+    nacNormalize(napGetCoeff(r));
+    t = nacInvers(napGetCoeff(r));
+    napMultN(q, t);
+    napNormalize(q);
+    nacDelete(&t,nacRing);
+    napDelete(&x);
+    napDelete(&r);
+    if (napGetExp(q,1) >= napGetExp(c,1))
+      q = napRemainder(q, c);
+    return q;
+  }
+  q = napMult(q, napCopy(qa));
+  q = napAdd(q, napInit(1));
+  qa = napNeg(qa);
+  loop
+  {
+    y = x;
+    x = r;
+    napDivMod(y, x, &qn, &r);
+    if (r==NULL)
+    {
+      break;
+    }
+    if (napGetExp(r,1)==0)
+    {
+      q = napMult(q, qn);
+      q = napNeg(q);
+      q = napAdd(q, qa);
+      nacNormalize(napGetCoeff(r));
+      t = nacInvers(napGetCoeff(r));
+      //nacNormalize(t);
+      napMultN(q, t);
+      napNormalize(q);
+      nacDelete(&t,nacRing);
+      napDelete(&x);
+      napDelete(&r);
+      if (napGetExp(q,1) >= napGetExp(c,1))
+        q = napRemainder(q, c);
+      return q;
+    }
+    y = q;
+    q = napMult(napCopy(q), qn);
+    q = napNeg(q);
+    q = napAdd(q, qa);
+    qa = y;
+  }
+// zero divisor found:
+zero_divisor:
+  Werror("zero divisor found - your minpoly is not irreducible");
+  return x;
+}
+
+#ifndef LONGALGNEW
+/*3
+* the degree of an napoly poly (used for test of "constant" et al.)
+*/
+static int  napDeg(napoly p)
+{
+  int  d = 0, i;
+
+  omCheckAddrSize(p,napMonomSize);
+  for (i = naNumbOfPar-1; i>=0; i--)
+    d += p->e[i];
+  return d;
+}
+#endif /* LONGALGNEW */
+
+/*3
+* the max degree of an napoly poly (used for test of "simple" et al.)
+*/
+static int  napMaxDeg(napoly p)
+{
+  int  d = 0;
+  while(p!=NULL)
+  {
+    d=si_max(d,napDeg(p));
+    napIter(p);
+  }
+  return d;
+}
+
+/*3
+* the max degree of an napoly poly (used for test of "simple" et al.)
+*/
+static int  napMaxDegLen(napoly p, int &l)
+{
+  int  d = 0;
+  int ll=0;
+  while(p!=NULL)
+  {
+    d=si_max(d,napDeg(p));
+    napIter(p);
+    ll++;
+  }
+  l=ll;
+  return d;
+}
+
+
+/*3
+*writes a polynomial number
+*/
+void napWrite(napoly p,const BOOLEAN has_denom)
+{
+  if (p==NULL)
+    StringAppendS("0");
+  else if (napIsConstant(p))
+  {
+    BOOLEAN kl=FALSE;
+    if (has_denom)
+    {
+      number den=nacRing->cf->n_GetDenom(napGetCoeff(p), nacRing);
+      kl=!n_IsOne(den,nacRing);
+      n_Delete(&den, nacRing);
+    }
+    if (kl) StringAppendS("(");
+    //StringAppendS("-1");
+    nacWrite(napGetCoeff(p));
+    if (kl) StringAppendS(")");
+  }
+  else
+  {
+    StringAppendS("(");
+    loop
+    {
+      BOOLEAN wroteCoeff=FALSE;
+      if ((napIsConstant(p))
+      || ((!nacIsOne(napGetCoeff(p)))
+        && (!nacIsMOne(napGetCoeff(p)))))
+      {
+        nacWrite(napGetCoeff(p));
+        wroteCoeff=(currRing->ShortOut==0);
+      }
+      else if (nacIsMOne(napGetCoeff(p)))
+      {
+        StringAppendS("-");
+      }
+      int  i;
+      for (i = 0; i < naNumbOfPar; i++)
+      {
+        if (napGetExp(p,i+1) > 0)
+        {
+          if (wroteCoeff)
+            StringAppendS("*");
+          else
+            wroteCoeff=(currRing->ShortOut==0);
+          StringAppendS(naParNames[i]);
+          if (napGetExp(p,(i+1)) > 1)
+          {
+            if (currRing->ShortOut == 0)
+              StringAppendS("^");
+            StringAppend("%d", napGetExp(p,i+1));
+          }
+        }
+      } /*for*/
+      napIter(p);
+      if (p==NULL)
+        break;
+      if (nacGreaterZero(napGetCoeff(p)))
+        StringAppendS("+");
+    }
+    StringAppendS(")");
+  }
+}
+
+
+#ifndef LONGALGNEW
+static char *napHandleMons(char *s, int i, PARAMETER_TYPE *ex)
+#else /* LONGALGNEW */
+static char *napHandleMons(char *s, int i, napoly ex)
+#endif /* LONGALGNEW */
+{
+  int  j;
+  if (strncmp(s,naParNames[i],strlen(naParNames[i]))==0)
+  {
+    s+=strlen(naParNames[i]);
+    if ((*s >= '0') && (*s <= '9'))
+    {
+      s = eati(s, &j);
+#ifndef LONGALGNEW
+      ex[i] += j;
+#else /* LONGALGNEW */
+      napAddExp(ex,i+1,j);
+#endif /* LONGALGNEW */
+    }
+    else
+#ifndef LONGALGNEW
+      ex[i]++;
+#else /* LONGALGNEW */
+      napAddExp(ex,i+1,1);
+#endif /* LONGALGNEW */
+  }
+  return s;
+}
+
+/*3  reads a monomial  */
+static char  *napRead(char *s, napoly *b)
+{
+  napoly a;
+  int  i;
+#ifndef LONGALGNEW
+  a = (napoly)omAlloc0(napMonomSize);
+#else /* LONGALGNEW */
+  a = (napoly)p_Init(nacRing);
+#endif /* LONGALGNEW */
+  if ((*s >= '0') && (*s <= '9'))
+  {
+    s = nacRead(s, &napGetCoeff(a));
+    if (nacIsZero(napGetCoeff(a)))
+    {
+      napDelete1(&a);
+      *b = NULL;
+      return s;
+    }
+  }
+  else
+    napGetCoeff(a) = nacInit(1);
+  i = 0;
+  char  *olds;
+  loop
+  {
+    olds = s;
+#ifndef LONGALGNEW
+    s = napHandleMons(s, i, a->e);
+#else /* LONGALGNEW */
+    s = napHandleMons(s, i, a);
+#endif /* LONGALGNEW */
+    if (olds == s)
+      i++;
+    else
+      i = 0;
+    if ((*s == '\0') || (i >= naNumbOfPar))
+      break;
+  }
+  *b = a;
+  return s;
+}
+
+static int napExp(napoly a, napoly b)
+{
+  while (napNext(a)!=NULL) napIter(a);
+  int m = napGetExp(a,1);
+  if (m==0) return 0;
+  while (napNext(b)!=NULL) napIter(b);
+  int mm=napGetExp(b,1);
+  if (m > mm) m = mm;
+  return m;
+}
+
+/*
+* finds the smallest i-th exponent in a and b
+* used to find it in a fraction
+*/
+static int napExpi(int i, napoly a, napoly b)
+{
+  if (a==NULL || b==NULL) return 0;
+  int m = napGetExp(a,i+1);
+  if (m==0) return 0;
+  while (napNext(a) != NULL)
+  {
+    napIter(a);
+    if (m > napGetExp(a,i+1))
+    {
+      m = napGetExp(a,i+1);
+      if (m==0) return 0;
+    }
+  }
+  do
+  {
+    if (m > napGetExp(b,i+1))
+    {
+      m = napGetExp(b,i+1);
+      if (m==0) return 0;
+    }
+    napIter(b);
+  }
+  while (b != NULL);
+  return m;
+}
+
+static void napContent(napoly ph)
+{
+  number h,d;
+  napoly p;
+
+  p = ph;
+  if (nacIsOne(napGetCoeff(p)))
+    return;
+  h = nacCopy(napGetCoeff(p));
+  napIter(p);
+  do
+  {
+    d=nacGcd(napGetCoeff(p), h, nacRing);
+    if(nacIsOne(d))
+    {
+      nacDelete(&h,nacRing);
+      nacDelete(&d,nacRing);
+      return;
+    }
+    nacDelete(&h,nacRing);
+    h = d;
+    napIter(p);
+  }
+  while (p!=NULL);
+  h = nacInvers(d);
+  nacDelete(&d,nacRing);
+  p = ph;
+  while (p!=NULL)
+  {
+    d = nacMult(napGetCoeff(p), h);
+    nacDelete(&napGetCoeff(p),nacRing);
+    napGetCoeff(p) = d;
+    napIter(p);
+  }
+  nacDelete(&h,nacRing);
+}
+
+static void napCleardenom(napoly ph)
+{
+  number d, h;
+  napoly p;
+
+  if (!naIsChar0)
+    return;
+  p = ph;
+  h = nacInit(1);
+  while (p!=NULL)
+  {
+    d = nacLcm(h, napGetCoeff(p), nacRing);
+    nacDelete(&h,nacRing);
+    h = d;
+    napIter(p);
+  }
+  if(!nacIsOne(h))
+  {
+    p = ph;
+    while (p!=NULL)
+    {
+      d=nacMult(h, napGetCoeff(p));
+      nacDelete(&napGetCoeff(p),nacRing);
+      nacNormalize(d);
+      napGetCoeff(p) = d;
+      napIter(p);
+    }
+    nacDelete(&h,nacRing);
+  }
+  napContent(ph);
+}
+
+static napoly napGcd0(napoly a, napoly b)
+{
+  number x, y;
+  if (!naIsChar0)
+    return napInit(1);
+  x = nacCopy(napGetCoeff(a));
+  if (nacIsOne(x))
+    return napInitz(x);
+  while (napNext(a)!=NULL)
+  {
+    napIter(a);
+    y = nacGcd(x, napGetCoeff(a), nacRing);
+    nacDelete(&x,nacRing);
+    x = y;
+    if (nacIsOne(x))
+      return napInitz(x);
+  }
+  do
+  {
+    y = nacGcd(x, napGetCoeff(b), nacRing);
+    nacDelete(&x,nacRing);
+    x = y;
+    if (nacIsOne(x))
+      return napInitz(x);
+    napIter(b);
+  }
+  while (b!=NULL);
+  return napInitz(x);
+}
+
+/*3
+* result =gcd(a,b)
+*/
+static napoly napGcd(napoly a, napoly b)
+{
+  int i;
+  napoly g, x, y, h;
+  if ((a==NULL)
+  || ((napNext(a)==NULL)&&(nacIsZero(napGetCoeff(a)))))
+  {
+    if ((b==NULL)
+    || ((napNext(b)==NULL)&&(nacIsZero(napGetCoeff(b)))))
+    {
+      return napInit(1);
+    }
+    return napCopy(b);
+  }
+  else
+  if ((b==NULL)
+  || ((napNext(b)==NULL)&&(nacIsZero(napGetCoeff(b)))))
+  {
+    return napCopy(a);
+  }
+  if (naMinimalPoly != NULL)
+  {
+    if (napGetExp(a,1) >= napGetExp(b,1))
+    {
+      x = a;
+      y = b;
+    }
+    else
+    {
+      x = b;
+      y = a;
+    }
+    if (!naIsChar0) g = napInit(1);
+    else            g = napGcd0(x, y);
+    if (napNext(y)==NULL)
+    {
+      napSetExp(g,1, napExp(x, y));
+      p_Setm(g,nacRing);
+      return g;
+    }
+    x = napCopy(x);
+    y = napCopy(y);
+    loop
+    {
+      h = napRemainder(x, y);
+      if (h==NULL)
+      {
+        napCleardenom(y);
+        if (!nacIsOne(napGetCoeff(g)))
+          napMultN(y, napGetCoeff(g));
+        napDelete1(&g);
+        return y;
+      }
+      else if (napNext(h)==NULL)
+        break;
+      x = y;
+      y = h;
+    }
+    napDelete(&y);
+    napDelete1(&h);
+    napSetExp(g,1, napExp(a, b));
+    p_Setm(g,nacRing);
+    return g;
+  }
+  // Hmm ... this is a memory leak
+#ifndef LONGALGNEW
+  // x = (napoly)omAlloc0(napMonomSize);
+#else /* LONGALGNEW */
+  // x = (napoly)p_Init(nacRing);
+#endif /* LONGALGNEW */
+  g=a;
+  h=b;
+  if (!naIsChar0) x = napInit(1);
+  else            x = napGcd0(g,h);
+  for (i=(naNumbOfPar-1); i>=0; i--)
+  {
+    napSetExp(x,i+1, napExpi(i,a,b));
+    p_Setm(x,nacRing);
+  }
+  return x;
+}
+
+
+number napLcm(napoly a)
+{
+  number h = nacInit(1);
+
+  if (naIsChar0)
+  {
+    number d;
+    napoly b = a;
+
+    while (b!=NULL)
+    {
+      d = nacLcm(h, napGetCoeff(b), nacRing);
+      nacDelete(&h,nacRing);
+      h = d;
+      napIter(b);
+    }
+  }
+  return h;
+}
+
+
+/*2
+* meins  (for reduction in algebraic extension)
+* checks if head of p divides head of q
+* doesn't delete p and q
+*/
+static BOOLEAN napDivPoly (napoly p, napoly q)
+{
+#ifndef LONGALGNEW
+  int j=0;   /* evtl. von naNumber.. -1 abwaerts zaehlen */
+#else /* LONGALGNEW */
+  int j=1;   /* evtl. von naNumber.. -1 abwaerts zaehlen */
+#endif /* LONGALGNEW */
+
+#ifndef LONGALGNEW
+  while (p->e[j] <= q->e[j])
+#else /* LONGALGNEW */
+  while (napGetExp(p,j) <= napGetExp(q,j))
+#endif /* LONGALGNEW */
+  {
+    j++;
+#ifndef LONGALGNEW
+    if (j >= naNumbOfPar)
+#else /* LONGALGNEW */
+    if (j > naNumbOfPar)
+#endif /* LONGALGNEW */
+      return 1;
+  }
+  return 0;
+}
+
+
+/*2
+* meins  (for reduction in algebraic extension)
+* Normalform of poly with naI
+* changes q and returns it
+*/
+napoly napRedp (napoly q)
+{
+#ifndef LONGALGNEW
+  napoly h = (napoly)omAlloc0(napMonomSize);
+#else /* LONGALGNEW */
+  napoly h = (napoly)p_Init(nacRing);
+#endif /* LONGALGNEW */
+  int i=0,j;
+
+  loop
+  {
+    if (napDivPoly (naI->liste[i], q))
+    {
+      /* h = lt(q)/lt(naI->liste[i])*/
+      napGetCoeff(h) = nacCopy(napGetCoeff(q));
+      for (j=naNumbOfPar; j>0; j--)
+        napSetExp(h,j, napGetExp(q,j) - napGetExp(naI->liste[i],j));
+      p_Setm(h,nacRing);
+      h = napMult (h, napCopy(naI->liste[i]));
+      h = napNeg (h);
+      q = napAdd (q, napCopy(h));
+      napDelete (&napNext(h));
+      if (q == NULL)
+      {
+        napDelete(&h);
+        return q;
+      }
+      /* try to reduce further */
+      i = 0;
+    }
+    else
+    {
+      i++;
+      if (i >= naI->anz)
+      {
+        napDelete(&h);
+        return q;
+      }
+    }
+  }
+}
+
+
+/*2
+* meins  (for reduction in algebraic extension)
+* reduces the tail of Poly q
+* needs q != NULL
+* changes q and returns it
+*/
+napoly napTailred (napoly q)
+{
+  napoly h;
+
+  h = napNext(q);
+  while (h != NULL)
+  {
+     h = napRedp (h);
+     if (h == NULL)
+        return q;
+     napIter(h);
+  }
+  return q;
+}
+
+
+/*================ procedure for rational functions: naXXXX =================*/
+
+/*2
+*  z:= i
+*/
+number naInit(int i)
+{
+  if (i!=0)
+  {
+#ifndef LONGALGNEW
+    lnumber l = (lnumber)omAllocBin(rnumber_bin);
+    l->z = napInit(i);
+    if (l->z==NULL)
+    {
+      omFreeBin((ADDRESS)l,  rnumber_bin);
+      return NULL;
+    }
+    l->s = 2;
+    l->n = NULL;
+    return (number)l;
+#else /* LONGALGNEW */
+    napoly z=napInit(i);
+    if (z!=NULL)
+    {
+      lnumber l = (lnumber)omAllocBin(rnumber_bin);
+      l->z = z;
+      l->s = 2;
+      l->n = NULL;
+      return (number)l;
+    }
+#endif /* LONGALGNEW */
+  }
+  /*else*/
+  return NULL;
+}
+
+number  naPar(int i)
+{
+  lnumber l = (lnumber)omAllocBin(rnumber_bin);
+  l->s = 2;
+  l->z = napInit(1);
+  napSetExp(l->z,i,1);
+  p_Setm(l->z,nacRing);
+  l->n = NULL;
+  return (number)l;
+}
+
+int     naParDeg(number n)     /* i := deg(n) */
+{
+  lnumber l = (lnumber)n;
+  if (l==NULL) return -1;
+  return napDeg(l->z);
+}
+
+//int     naParDeg(number n)     /* i := deg(n) */
+//{
+//  lnumber l = (lnumber)n;
+//  if (l==NULL) return -1;
+//  return napMaxDeg(l->z)+napMaxDeg(l->n);
+//}
+
+int     naSize(number n)     /* size desc. */
+{
+  lnumber l = (lnumber)n;
+  if (l==NULL) return -1;
+  int len_z;
+  int len_n;
+  int o=napMaxDegLen(l->z,len_z)+napMaxDegLen(l->n,len_n);
+  return (len_z+len_n)+o;
+}
+
+/*2
+* convert a number to int (if possible)
+*/
+int naInt(number &n)
+{
+  lnumber l=(lnumber)n;
+  if ((l!=NULL)&&(l->n==NULL)&&(napIsConstant(l->z)))
+  {
+    return nacInt(napGetCoeff(l->z));
+  }
+  return 0;
+}
+
+/*2
+*  deletes p
+*/
+void naDelete(number *p, const ring r)
+{
+  lnumber l = (lnumber) * p;
+  if (l==NULL) return;
+  nap_Delete(&(l->z),r);
+  nap_Delete(&(l->n),r);
+  omFreeBin((ADDRESS)l,  rnumber_bin);
+  *p = NULL;
+}
+
+/*2
+* copy p to erg
+*/
+number naCopy(number p)
+{
+  if (p==NULL) return NULL;
+  naTest(p);
+  lnumber erg;
+  lnumber src = (lnumber)p;
+  erg = (lnumber)omAlloc0Bin(rnumber_bin);
+  erg->z = napCopy(src->z);
+  erg->n = napCopy(src->n);
+  erg->s = src->s;
+  return (number)erg;
+}
+number na_Copy(number p, const ring r)
+{
+  if (p==NULL) return NULL;
+  lnumber erg;
+  lnumber src = (lnumber)p;
+  erg = (lnumber)omAlloc0Bin(rnumber_bin);
+  erg->z = nap_Copy(src->z,r);
+  erg->n = nap_Copy(src->n,r);
+  erg->s = src->s;
+  return (number)erg;
+}
+
+/*2
+* a dummy number: 0
+*/
+void naNew(number *z)
+{
+  *z = NULL;
+}
+
+/*2
+*  addition; lu:= la + lb
+*/
+number naAdd(number la, number lb)
+{
+  napoly x, y;
+  lnumber lu;
+  lnumber a = (lnumber)la;
+  lnumber b = (lnumber)lb;
+  if (a==NULL) return naCopy(lb);
+  if (b==NULL) return naCopy(la);
+  omCheckAddrSize(a,sizeof(snumber));
+  omCheckAddrSize(b,sizeof(snumber));
+  lu = (lnumber)omAllocBin(rnumber_bin);
+  if (b->n!=NULL) x = napMultCopy(a->z, b->n);
+  else            x = napCopy(a->z);
+  if (a->n!=NULL) y = napMultCopy(b->z, a->n);
+  else            y = napCopy(b->z);
+  lu->z = napAdd(x, y);
+  if (lu->z==NULL)
+  {
+    omFreeBin((ADDRESS)lu,  rnumber_bin);
+    return (number)NULL;
+  }
+  if (a->n!=NULL)
+  {
+    if (b->n!=NULL) x = napMultCopy(a->n, b->n);
+    else            x = napCopy(a->n);
+  }
+  else
+  {
+    if (b->n!=NULL) x = napCopy(b->n);
+    else            x = NULL;
+  }
+#ifndef LONGALGNEW
+  if ((x!=NULL) && (napDeg(x)==0) && nacIsOne(x->ko))
+    napDelete(&x);
+#else /* LONGALGNEW */
+  if (x!=NULL)
+  {
+    assume(!napIsConstant(x));
+  }
+#endif /* LONGALGNEW */
+  lu->n = x;
+  lu->s = 0;
+#ifdef LONGALGNEW
+  if (lu->n!=NULL)
+  {
+     number luu=(number)lu;
+     naNormalize(luu);
+     lu=(lnumber)luu;
+  }
+#endif /* LONGALGNEW */
+  naTest((number)lu);
+  return (number)lu;
+}
+
+/*2
+*  subtraction; r:= la - lb
+*/
+number naSub(number la, number lb)
+{
+  lnumber lu;
+
+  if (lb==NULL) return naCopy(la);
+  if (la==NULL)
+  {
+    lu = (lnumber)naCopy(lb);
+    lu->z = napNeg(lu->z);
+    return (number)lu;
+  }
+
+  napoly x, y;
+  lnumber a = (lnumber)la;
+  lnumber b = (lnumber)lb;
+
+  omCheckAddrSize(a,sizeof(snumber));
+  omCheckAddrSize(b,sizeof(snumber));
+  lu = (lnumber)omAllocBin(rnumber_bin);
+  if (b->n!=NULL) x = napMultCopy(a->z, b->n);
+  else            x = napCopy(a->z);
+  if (a->n!=NULL) y = napMult(napCopy(b->z), napCopyNeg(a->n));
+  else            y = napCopyNeg(b->z);
+  lu->z = napAdd(x, y);
+  if (lu->z==NULL)
+  {
+    omFreeBin((ADDRESS)lu,  rnumber_bin);
+    return (number)NULL;
+  }
+  if (a->n!=NULL)
+  {
+    if (b->n!=NULL) x = napMultCopy(a->n, b->n);
+    else            x = napCopy(a->n);
+  }
+  else
+  {
+    if (b->n!=NULL) x = napCopy(b->n);
+    else            x = NULL;
+  }
+#ifndef LONGALGNEW
+  if ((x!=NULL)&& (napDeg(x)==0) && nacIsOne(x->ko))
+    napDelete(&x);
+#else /* LONGALGNEW */
+  if (x!=NULL)
+  {
+    assume(!napIsConstant(x));
+  }
+#endif /* LONGALGNEW */
+  lu->n = x;
+  lu->s = 0;
+#ifdef LONGALGNEW
+  if (lu->n!=NULL)
+  {
+     number luu=(number)lu;
+     naNormalize(luu);
+     lu=(lnumber)luu;
+  }
+#endif /* LONGALGNEW */
+  naTest((number)lu);
+  return (number)lu;
+}
+
+/*2
+*  multiplication; r:= la * lb
+*/
+number naMult(number la, number lb)
+{
+  if ((la==NULL) || (lb==NULL))
+    return NULL;
+
+  lnumber a = (lnumber)la;
+  lnumber b = (lnumber)lb;
+  lnumber lo;
+  napoly x;
+
+  omCheckAddrSize(a,sizeof(snumber));
+  omCheckAddrSize(b,sizeof(snumber));
+  naTest(la);
+  naTest(lb);
+
+  lo = (lnumber)omAllocBin(rnumber_bin);
+  lo->z = napMultCopy(a->z, b->z);
+
+  if (a->n==NULL)
+  {
+    if (b->n==NULL)
+      x = NULL;
+    else
+      x = napCopy(b->n);
+  }
+  else
+  {
+    if (b->n==NULL)
+    {
+      x = napCopy(a->n);
+    }
+    else
+    {
+      x = napMultCopy(b->n, a->n);
+    }
+  }
+  if (naMinimalPoly!=NULL)
+  {
+    if (napGetExp(lo->z,1) >= napGetExp(naMinimalPoly,1))
+      lo->z = napRemainder(lo->z, naMinimalPoly);
+    if ((x!=NULL) && (napGetExp(x,1) >= napGetExp(naMinimalPoly,1)))
+      x = napRemainder(x, naMinimalPoly);
+  }
+  if (naI!=NULL)
+  {
+    lo->z = napRedp (lo->z);
+    if (lo->z != NULL)
+       lo->z = napTailred (lo->z);
+    if (x!=NULL)
+    {
+      x = napRedp (x);
+      if (x!=NULL)
+        x = napTailred (x);
+    }
+  }
+  if ((x!=NULL) && (napIsConstant(x)) && nacIsOne(napGetCoeff(x)))
+    napDelete(&x);
+  lo->n = x;
+  lo->s = 0;
+  if(lo->z==NULL)
+  {
+    omFreeBin((ADDRESS)lo, rnumber_bin);
+    lo=NULL;
+  }
+#if 0
+  if (lo->n!=NULL)
+  {
+     number luu=(number)lo;
+     naNormalize(luu);
+     lo=(lnumber)luu;
+  }
+#endif
+  naTest((number)lo);
+  return (number)lo;
+}
+
+number naIntDiv(number la, number lb)
+{
+  lnumber res;
+  lnumber a = (lnumber)la;
+  lnumber b = (lnumber)lb;
+#ifndef LONGALGNEW
+  if ((a==NULL) || (a->z==NULL))
+#else /* LONGALGNEW */
+  if (a==NULL)
+  {
+    assume(a->z!=NULL);
+#endif /* LONGALGNEW */
+    return NULL;
+#ifndef LONGALGNEW
+  if ((b==NULL) || (b->z==NULL))
+#else /* LONGALGNEW */
+  }
+  if (b==NULL)
+#endif /* LONGALGNEW */
+  {
+#ifdef LONGALGNEW
+    assume(b->z!=NULL);
+#endif /* LONGALGNEW */
+    WerrorS("div. by 0");
+    return NULL;
+  }
+  assume(a->z!=NULL && b->z!=NULL);
+  assume(a->n==NULL && b->n==NULL);
+  res = (lnumber)omAllocBin(rnumber_bin);
+  res->z = napCopy(a->z);
+  res->n = napCopy(b->z);
+  res->s = 0;
+  number nres=(number)res;
+  naNormalize(nres);
+
+  //napDelete(&res->n);
+  naTest(nres);
+  return nres;
+}
+
+/*2
+*  division; lo:= la / lb
+*/
+number naDiv(number la, number lb)
+{
+  lnumber lo;
+  lnumber a = (lnumber)la;
+  lnumber b = (lnumber)lb;
+  napoly x;
+
+  if ((a==NULL) || (a->z==NULL))
+    return NULL;
+
+  if ((b==NULL) || (b->z==NULL))
+  {
+    WerrorS("div. by 0");
+    return NULL;
+  }
+  omCheckAddrSize(a,sizeof(snumber));
+  omCheckAddrSize(b,sizeof(snumber));
+  lo = (lnumber)omAllocBin(rnumber_bin);
+  if (b->n!=NULL)
+    lo->z = napMultCopy(a->z, b->n);
+  else
+    lo->z = napCopy(a->z);
+  if (a->n!=NULL)
+    x = napMultCopy(b->z, a->n);
+  else
+    x = napCopy(b->z);
+  if (naMinimalPoly!=NULL)
+  {
+    if (napGetExp(lo->z,1) >= napGetExp(naMinimalPoly,1))
+      lo->z = napRemainder(lo->z, naMinimalPoly);
+    if (napGetExp(x,1) >= napGetExp(naMinimalPoly,1))
+      x = napRemainder(x, naMinimalPoly);
+  }
+  if (naI!=NULL)
+  {
+    lo->z = napRedp (lo->z);
+    if (lo->z != NULL)
+       lo->z = napTailred (lo->z);
+    if (x!=NULL)
+    {
+      x = napRedp (x);
+      if (x!=NULL)
+        x = napTailred (x);
+    }
+  }
+  if ((napIsConstant(x)) && nacIsOne(napGetCoeff(x)))
+    napDelete(&x);
+  lo->s = 0;
+  lo->n = x;
+#ifdef LONGALGNEW
+  if (lo->n!=NULL)
+  {
+     number luu=(number)lo;
+     naNormalize(luu);
+     lo=(lnumber)luu;
+  }
+#endif /* LONGALGNEW */
+  naTest((number)lo);
+  return (number)lo;
+}
+
+/*2
+*  za:= - za
+*/
+number naNeg(number za)
+{
+  if (za!=NULL)
+  {
+    lnumber e = (lnumber)za;
+    naTest(za);
+    e->z = napNeg(e->z);
+  }
+  return za;
+}
+
+/*2
+* 1/a
+*/
+number naInvers(number a)
+{
+  lnumber lo;
+  lnumber b = (lnumber)a;
+  napoly x;
+
+  if (b==NULL)
+  {
+    WerrorS("div. by 0");
+    return NULL;
+  }
+  omCheckAddrSize(b,sizeof(snumber));
+  lo = (lnumber)omAlloc0Bin(rnumber_bin);
+  lo->s = b->s;
+  if (b->n!=NULL)
+    lo->z = napCopy(b->n);
+  else
+    lo->z = napInit(1);
+  x = b->z;
+  if ((!napIsConstant(x)) || !nacIsOne(napGetCoeff(x)))
+    x = napCopy(x);
+  else
+  {
+    lo->n = NULL;
+    naTest((number)lo);
+    return (number)lo;
+  }
+  if (naMinimalPoly!=NULL)
+  {
+    x = napInvers(x, naMinimalPoly);
+    x = napMult(x, lo->z);
+    if (napGetExp(x,1) >= napGetExp(naMinimalPoly,1))
+      x = napRemainder(x, naMinimalPoly);
+    lo->z = x;
+    lo->n = NULL;
+    lo->s = 2;
+    while (x!=NULL)
+    {
+      nacNormalize(napGetCoeff(x));
+      napIter(x);
+    }
+  }
+  else
+    lo->n = x;
+#ifdef LONGALGNEW
+  if (lo->n!=NULL)
+  {
+     number luu=(number)lo;
+     naNormalize(luu);
+     lo=(lnumber)luu;
+  }
+#endif /* LONGALGNEW */
+  naTest((number)lo);
+  return (number)lo;
+}
+
+
+BOOLEAN naIsZero(number za)
+{
+  lnumber zb = (lnumber)za;
+  naTest(za);
+#ifdef LDEBUG
+  if ((zb!=NULL) && (zb->z==NULL)) WerrorS("internal zero error(2)");
+#endif
+  return ((zb==NULL) || (zb->z==NULL));
+}
+
+
+BOOLEAN naGreaterZero(number za)
+{
+  lnumber zb = (lnumber)za;
+#ifdef LDEBUG
+  if ((zb!=NULL) && (zb->z==NULL)) WerrorS("internal zero error(3)");
+#endif
+  naTest(za);
+  if ((zb!=NULL) && (zb->z!=NULL))
+  {
+    if (zb->n!=NULL)
+    {
+      if ((napIsConstant(zb->z)) && !nacGreaterZero(napGetCoeff(zb->z)))
+        return FALSE;
+      return TRUE;
+    }
+    if ((napIsConstant(zb->z)) && !nacGreaterZero(napGetCoeff(zb->z)))
+      return FALSE;
+  }
+  return TRUE;
+}
+
+
+/*2
+* a = b ?
+*/
+BOOLEAN naEqual (number a, number b)
+{
+  if(a==b) return TRUE;
+  if((a==NULL)&&(b!=NULL)) return FALSE;
+  if((b==NULL)&&(a!=NULL)) return FALSE;
+
+  lnumber aa=(lnumber)a;
+  lnumber bb=(lnumber)b;
+
+  int an_deg=0;
+  if(aa->n!=NULL)
+    an_deg=napDeg(aa->n);
+  int bn_deg=0;
+  if(bb->n!=NULL)
+    bn_deg=napDeg(bb->n);
+  if(an_deg+napDeg(bb->z)!=bn_deg+napDeg(aa->z))
+    return FALSE;
+#if 0
+  naNormalize(a);
+  aa=(lnumber)a;
+  naNormalize(b);
+  bb=(lnumber)b;
+  if((aa->n==NULL)&&(bb->n!=NULL)) return FALSE;
+  if((bb->n==NULL)&&(aa->n!=NULL)) return FALSE;
+  if(napComp(aa->z,bb->z)!=0) return FALSE;
+  if((aa->n!=NULL) && (napComp(aa->n,bb->n))) return FALSE;
+#endif
+  number h = naSub(a, b);
+  BOOLEAN bo = naIsZero(h);
+  naDelete(&h,currRing);
+  return bo;
+}
+
+
+BOOLEAN naGreater (number a, number b)
+{
+  if (naIsZero(a))
+    return FALSE;
+  if (naIsZero(b))
+    return TRUE; /* a!= 0)*/
+  return napDeg(((lnumber)a)->z)>napDeg(((lnumber)b)->z);
+}
+
+/*2
+* reads a number
+*/
+char  *naRead(char *s, number *p)
+{
+  napoly x;
+  lnumber a;
+  s = napRead(s, &x);
+  if (x==NULL)
+  {
+    *p = NULL;
+    return s;
+  }
+  *p = (number)omAlloc0Bin(rnumber_bin);
+  a = (lnumber)*p;
+  if ((naMinimalPoly!=NULL)
+  && (napGetExp(x,1) >= napGetExp(naMinimalPoly,1)))
+    a->z = napRemainder(x, naMinimalPoly);
+  else if (naI!=NULL)
+  {
+    a->z = napRedp(x);
+    if (a->z != NULL)
+      a->z = napTailred (a->z);
+  }
+  else
+    a->z = x;
+  if(a->z==NULL)
+  {
+    omFreeBin((ADDRESS)*p, rnumber_bin);
+    *p=NULL;
+  }
+  else
+  {
+    a->n = NULL;
+    a->s = 0;
+    naTest(*p);
+  }
+  return s;
+}
+
+/*2
+* tries to convert a number to a name
+*/
+char * naName(number n)
+{
+  lnumber ph = (lnumber)n;
+  if ((ph==NULL)||(ph->z==NULL))
+    return NULL;
+  int i;
+  char *s=(char *)omAlloc(4* naNumbOfPar);
+  char *t=(char *)omAlloc(8);
+  s[0]='\0';
+  for (i = 0; i <= naNumbOfPar - 1; i++)
+  {
+    if (napGetExp(ph->z,i+1) > 0)
+    {
+      if (napGetExp(ph->z,i+1) >1)
+      {
+        sprintf(t,"%s%d",naParNames[i],(int)napGetExp(ph->z,i+1));
+        strcat(s,t);
+      }
+      else
+      {
+        strcat(s,naParNames[i]);
+      }
+    }
+  }
+  omFreeSize((ADDRESS)t,8);
+  if (s[0]=='\0')
+  {
+    omFree((ADDRESS)s);
+    return NULL;
+  }
+  return s;
+}
+
+/*2
+*  writes a number
+*/
+void naWrite(number &phn)
+{
+  lnumber ph = (lnumber)phn;
+  if ((ph==NULL)||(ph->z==NULL))
+    StringAppendS("0");
+  else
+  {
+    phn->s = 0;
+    naNormalize(phn);
+    BOOLEAN has_denom=(ph->n!=NULL);
+    napWrite(ph->z,has_denom/*(ph->n!=NULL)*/);
+    if (has_denom/*(ph->n!=NULL)*/)
+    {
+      StringAppendS("/");
+      napWrite(ph->n,TRUE);
+    }
+  }
+}
+
+/*2
+* za == 1 ?
+*/
+BOOLEAN naIsOne(number za)
+{
+  lnumber a = (lnumber)za;
+  napoly x, y;
+  number t;
+  if (a==NULL) return FALSE;
+  omCheckAddrSize(a,sizeof(snumber));
+#ifdef LDEBUG
+  if (a->z==NULL) WerrorS("internal zero error(4)");
+#endif
+  if (a->n==NULL)
+  {
+    if (napIsConstant(a->z)) return nacIsOne(napGetCoeff(a->z));
+    else                 return FALSE;
+  }
+  x = a->z;
+  y = a->n;
+  do
+  {
+    if (napComp(x, y))
+      return FALSE;
+    else
+    {
+      t = nacSub(napGetCoeff(x), napGetCoeff(y));
+      if (!nacIsZero(t))
+      {
+        nacDelete(&t,nacRing);
+        return FALSE;
+      }
+      else
+        nacDelete(&t,nacRing);
+    }
+    napIter(x);
+    napIter(y);
+  }
+  while ((x!=NULL) && (y!=NULL));
+  if ((x!=NULL) || (y!=NULL)) return FALSE;
+  napDelete(&a->z);
+  napDelete(&a->n);
+  a->z = napInit(1);
+  a->n = NULL;
+  a->s = 2;
+  return TRUE;
+}
+
+/*2
+* za == -1 ?
+*/
+BOOLEAN naIsMOne(number za)
+{
+  lnumber a = (lnumber)za;
+  napoly x, y;
+  number t;
+  if (a==NULL) return FALSE;
+  omCheckAddrSize(a,sizeof(snumber));
+#ifdef LDEBUG
+  if (a->z==NULL)
+  {
+    WerrorS("internal zero error(5)");
+    return FALSE;
+  }
+#endif
+  if (a->n==NULL)
+  {
+    if (napIsConstant(a->z)) return nacIsMOne(napGetCoeff(a->z));
+    /*else                   return FALSE;*/
+  }
+  return FALSE;
+}
+
+/*2
+* returns the i-th power of p (i>=0)
+*/
+void naPower(number p, int i, number *rc)
+{
+  number x;
+  *rc = naInit(1);
+  for (; i > 0; i--)
+  {
+    x = naMult(*rc, p);
+    naDelete(rc,currRing);
+    *rc = x;
+  }
+}
+
+/*2
+* result =gcd(a,b)
+*/
+number naGcd(number a, number b, const ring r)
+{
+  lnumber x, y;
+  lnumber result = (lnumber)omAlloc0Bin(rnumber_bin);
+
+  x = (lnumber)a;
+  y = (lnumber)b;
+  if (naNumbOfPar == 1)
+  {
+    if (naMinimalPoly!=NULL)
+    {
+      if (napNext(x->z)!=NULL)
+        result->z = napCopy(x->z);
+      else
+        result->z = napGcd0(x->z, y->z);
+    }
+    else
+      result->z = napGcd(x->z, y->z);
+  }
+  else
+    result->z = napGcd(x->z, y->z); // change from napGcd0
+  naTest((number)result);
+  return (number)result;
+}
+
+/*2
+* naNumbOfPar = 1:
+* clears denominator         algebraic case;
+* tries to simplify ratio    transcendental case;
+*
+* cancels monomials
+* occuring in denominator
+* and enumerator  ?          naNumbOfPar != 1;
+*
+* #defines for Factory:
+* FACTORY_GCD_TEST: do not apply built in gcd for
+*   univariate polynomials, always use Factory
+*/
+void naNormalize(number &pp)
+{
+
+  //naTest(pp); // input may not be "normal"
+  lnumber p = (lnumber)pp;
+
+  if ((p==NULL) /*|| (p->s==2)*/)
+    return;
+  p->s = 2;
+  napoly x = p->z;
+  napoly y = p->n;
+  if ((y!=NULL) && (naMinimalPoly!=NULL))
+  {
+    y = napInvers(y, naMinimalPoly);
+    x = napMult(x, y);
+    if (napGetExp(x,1) >= napGetExp(naMinimalPoly,1))
+      x = napRemainder(x, naMinimalPoly);
+    p->z = x;
+    p->n = y = NULL;
+  }
+  /* check for degree of x too high: */
+  if ((x!=NULL) && (naMinimalPoly!=NULL) && (x!=naMinimalPoly)
+  && (napGetExp(x,1)>napGetExp(naMinimalPoly,1)))
+  // DO NOT REDUCE naMinimalPoly with itself
+  {
+    x = napRemainder(x, naMinimalPoly);
+    p->z = x;
+  }
+  /* normalize all coefficients in n and z (if in Q) */
+  if (naIsChar0)
+  {
+    while(x!=NULL)
+    {
+      nacNormalize(napGetCoeff(x));
+      napIter(x);
+    }
+    x = p->z;
+  }
+  if (y==NULL) return;
+  if (naIsChar0)
+  {
+    while(y!=NULL)
+    {
+      nacNormalize(napGetCoeff(y));
+      napIter(y);
+    }
+    y = p->n;
+  }
+  // p->n !=NULL:
+  /* collect all denoms from y and multiply x and y by it */
+  if (naIsChar0)
+  {
+    number n=napLcm(y);
+    napMultN(x,n);
+    napMultN(y,n);
+    nacDelete(&n,nacRing);
+    while(x!=NULL)
+    {
+      nacNormalize(napGetCoeff(x));
+      napIter(x);
+    }
+    x = p->z;
+    while(y!=NULL)
+    {
+      nacNormalize(napGetCoeff(y));
+      napIter(y);
+    }
+    y = p->n;
+  }
+  if (naMinimalPoly == NULL)
+  {
+    int i;
+    for (i=naNumbOfPar-1; i>=0; i--)
+    {
+      napoly xx=x;
+      napoly yy=y;
+      int m = napExpi(i, yy, xx);
+      if (m != 0)          // in this case xx!=NULL!=yy
+      {
+        while (xx != NULL)
+        {
+          napAddExp(xx,i+1, -m);
+          napIter(xx);
+        }
+        while (yy != NULL)
+        {
+          napAddExp(yy,i+1, -m);
+          napIter(yy);
+        }
+      }
+    }
+  }
+  if (napIsConstant(y)) /* i.e. => simplify to (1/c)*z / monom */
+  {
+    if (nacIsOne(napGetCoeff(y)))
+    {
+      napDelete1(&y);
+      p->n = NULL;
+      naTest(pp);
+      return;
+    }
+    number h1 = nacInvers(napGetCoeff(y));
+    nacNormalize(h1);
+    napMultN(x, h1);
+    nacDelete(&h1,nacRing);
+    napDelete1(&y);
+    p->n = NULL;
+    naTest(pp);
+    return;
+  }
+#ifndef FACTORY_GCD_TEST
+  if (naNumbOfPar == 1) /* apply built-in gcd */
+  {
+    napoly x1,y1;
+    if (napGetExp(x,1) >= napGetExp(y,1))
+    {
+      x1 = napCopy(x);
+      y1 = napCopy(y);
+    }
+    else
+    {
+      x1 = napCopy(y);
+      y1 = napCopy(x);
+    }
+    napoly r;
+    loop
+    {
+      r = napRemainder(x1, y1);
+      if ((r==NULL) || (napNext(r)==NULL)) break;
+      x1 = y1;
+      y1 = r;
+    }
+    if (r!=NULL)
+    {
+      napDelete(&r);
+      napDelete(&y1);
+    }
+    else
+    {
+      napDivMod(x, y1, &(p->z), &r);
+      napDivMod(y, y1, &(p->n), &r);
+      napDelete(&y1);
+    }
+    x = p->z;
+    y = p->n;
+    /* collect all denoms from y and multiply x and y by it */
+    if (naIsChar0)
+    {
+      number n=napLcm(y);
+      napMultN(x,n);
+      napMultN(y,n);
+      nacDelete(&n,nacRing);
+      while(x!=NULL)
+      {
+        nacNormalize(napGetCoeff(x));
+        napIter(x);
+      }
+      x = p->z;
+      while(y!=NULL)
+      {
+        nacNormalize(napGetCoeff(y));
+        napIter(y);
+      }
+      y = p->n;
+    }
+    if (napNext(y)==NULL)
+    {
+      if (nacIsOne(napGetCoeff(y)))
+      {
+        if (napGetExp(y,1)==0)
+        {
+          napDelete1(&y);
+          p->n = NULL;
+        }
+        naTest(pp);
+        return;
+      }
+    }
+  }
+#endif /* FACTORY_GCD_TEST */
+#ifdef HAVE_FACTORY
+#ifndef FACTORY_GCD_TEST
+  else
+#endif
+  {
+    napoly xx,yy;
+    singclap_algdividecontent(x,y,xx,yy);
+    if (xx!=NULL)
+    {
+      p->z=xx;
+      p->n=yy;
+      napDelete(&x);
+      napDelete(&y);
+    }
+  }
+#endif
+  /* remove common factors from z and n */
+  x=p->z;
+  y=p->n;
+  if(!nacGreaterZero(napGetCoeff(y)))
+  {
+    x=napNeg(x);
+    y=napNeg(y);
+  }
+  number g=nacCopy(napGetCoeff(x));
+  napIter(x);
+  while (x!=NULL)
+  {
+    number d=nacGcd(g,napGetCoeff(x), nacRing);
+    if(nacIsOne(d))
+    {
+      nacDelete(&g,nacRing);
+      nacDelete(&d,nacRing);
+      naTest(pp);
+      return;
+    }
+    nacDelete(&g,nacRing);
+    g = d;
+    napIter(x);
+  }
+  while (y!=NULL)
+  {
+    number d=nacGcd(g,napGetCoeff(y), nacRing);
+    if(nacIsOne(d))
+    {
+      nacDelete(&g,nacRing);
+      nacDelete(&d,nacRing);
+      naTest(pp);
+      return;
+    }
+    nacDelete(&g,nacRing);
+    g = d;
+    napIter(y);
+  }
+  x=p->z;
+  y=p->n;
+  while (x!=NULL)
+  {
+    number d = nacIntDiv(napGetCoeff(x),g);
+    napSetCoeff(x,d);
+    napIter(x);
+  }
+  while (y!=NULL)
+  {
+    number d = nacIntDiv(napGetCoeff(y),g);
+    napSetCoeff(y,d);
+    napIter(y);
+  }
+  nacDelete(&g,nacRing);
+  naTest(pp);
+}
+
+/*2
+* returns in result->n 1
+* and in     result->z the lcm(a->z,b->n)
+*/
+number naLcm(number la, number lb, const ring r)
+{
+  lnumber result;
+  lnumber a = (lnumber)la;
+  lnumber b = (lnumber)lb;
+  result = (lnumber)omAlloc0Bin(rnumber_bin);
+  //if (((naMinimalPoly==NULL) && (naI==NULL)) || !naIsChar0)
+  //{
+  //  result->z = napInit(1);
+  //  return (number)result;
+  //}
+  naNormalize(lb);
+  naTest(la);
+  naTest(lb);
+  napoly x = napCopy(a->z);
+  number t = napLcm(b->z); // get all denom of b->z
+  if (!nacIsOne(t))
+  {
+    number bt, r;
+    napoly xx=x;
+    while (xx!=NULL)
+    {
+      bt = nacGcd(t, napGetCoeff(xx), nacRing);
+      r = nacMult(t, napGetCoeff(xx));
+      nacDelete(&napGetCoeff(xx),nacRing);
+      napGetCoeff(xx) = nacDiv(r, bt);
+      nacNormalize(napGetCoeff(xx));
+      nacDelete(&bt,nacRing);
+      nacDelete(&r,nacRing);
+      napIter(xx);
+    }
+  }
+  nacDelete(&t,nacRing);
+  result->z = x;
+#ifdef HAVE_FACTORY
+  if (b->n!=NULL)
+  {
+    result->z=singclap_alglcm(result->z,b->n);
+    napDelete(&x);
+  }
+#endif
+  naTest(la);
+  naTest(lb);
+  naTest((number)result);
+  return ((number)result);
+}
+
+/*2
+* input: a set of constant polynomials
+* sets the global variable naI
+*/
+void naSetIdeal(ideal I)
+{
+  int i;
+
+  if (idIs0(I))
+  {
+    for (i=naI->anz-1; i>=0; i--)
+      napDelete(&naI->liste[i]);
+    omFreeBin((ADDRESS)naI, snaIdeal_bin);
+    naI=NULL;
+  }
+  else
+  {
+    lnumber h;
+    number a;
+    napoly x;
+
+    naI=(naIdeal)omAllocBin(snaIdeal_bin);
+    naI->anz=IDELEMS(I);
+    naI->liste=(napoly*)omAlloc(naI->anz*sizeof(napoly));
+    for (i=IDELEMS(I)-1; i>=0; i--)
+    {
+      h=(lnumber)pGetCoeff(I->m[i]);
+      /* We only need the enumerator of h, as we expect it to be a polynomial */
+      naI->liste[i]=napCopy(h->z);
+      /* If it isn't normalized (lc = 1) do this */
+      if (!nacIsOne(napGetCoeff(naI->liste[i])))
+      {
+        x=naI->liste[i];
+	nacNormalize(napGetCoeff(x));
+        a=nacCopy(napGetCoeff(x));
+        number aa=nacInvers(a);
+        nacDelete(&a,nacRing);
+        napMultN(x,aa);
+        nacDelete(&aa,nacRing);
+      }
+    }
+  }
+}
+
+/*2
+* map Z/p -> Q(a)
+*/
+number naMapP0(number c)
+{
+  if (npIsZero(c)) return NULL;
+  lnumber l=(lnumber)omAllocBin(rnumber_bin);
+  l->s=2;
+#ifndef LONGALGNEW
+  l->z=(napoly)omAlloc0(napMonomSize);
+#else /* LONGALGNEW */
+  l->z=(napoly)p_Init(nacRing);
+#endif /* LONGALGNEW */
+  int i=(int)c;
+  if (i>(naPrimeM>>2)) i-=naPrimeM;
+  napGetCoeff(l->z)=nlInit(i);
+  l->n=NULL;
+  return (number)l;
+}
+
+/*2
+* map Q -> Q(a)
+*/
+number naMap00(number c)
+{
+  if (nlIsZero(c)) return NULL;
+  lnumber l=(lnumber)omAllocBin(rnumber_bin);
+  l->s=0;
+#ifndef LONGALGNEW
+  l->z=(napoly)omAlloc0(napMonomSize);
+#else /* LONGALGNEW */
+  l->z=(napoly)p_Init(nacRing);
+#endif /* LONGALGNEW */
+  napGetCoeff(l->z)=nlCopy(c);
+  l->n=NULL;
+  return (number)l;
+}
+
+/*2
+* map Z/p -> Z/p(a)
+*/
+number naMapPP(number c)
+{
+  if (npIsZero(c)) return NULL;
+  lnumber l=(lnumber)omAllocBin(rnumber_bin);
+  l->s=2;
+#ifndef LONGALGNEW
+  l->z=(napoly)omAlloc0(napMonomSize);
+#else /* LONGALGNEW */
+  l->z=(napoly)p_Init(nacRing);
+#endif /* LONGALGNEW */
+  napGetCoeff(l->z)=c; /* omit npCopy, because npCopy is a no-op */
+  l->n=NULL;
+  return (number)l;
+}
+
+/*2
+* map Z/p' -> Z/p(a)
+*/
+number naMapPP1(number c)
+{
+  if (npIsZero(c)) return NULL;
+  int i=(int)c;
+  if (i>naPrimeM) i-=naPrimeM;
+  number n=npInit(i);
+  if (npIsZero(n)) return NULL;
+  lnumber l=(lnumber)omAllocBin(rnumber_bin);
+  l->s=2;
+#ifndef LONGALGNEW
+  l->z=(napoly)omAlloc0(napMonomSize);
+#else /* LONGALGNEW */
+  l->z=(napoly)p_Init(nacRing);
+#endif /* LONGALGNEW */
+  napGetCoeff(l->z)=n;
+  l->n=NULL;
+  return (number)l;
+}
+
+/*2
+* map Q -> Z/p(a)
+*/
+number naMap0P(number c)
+{
+  if (nlIsZero(c)) return NULL;
+  number n=npInit(nlInt(c));
+  if (npIsZero(n)) return NULL;
+  lnumber l=(lnumber)omAllocBin(rnumber_bin);
+  l->s=2;
+#ifndef LONGALGNEW
+  l->z=(napoly)omAlloc0(napMonomSize);
+#else /* LONGALGNEW */
+  l->z=(napoly)p_Init(nacRing);
+#endif /* LONGALGNEW */
+  napGetCoeff(l->z)=n;
+  l->n=NULL;
+  return (number)l;
+}
+
+static number (*nacMap)(number);
+static int naParsToCopy;
+#ifdef LONGALGNEW
+static ring napMapRing;
+#endif /* LONGALGNEW */
+static napoly napMap(napoly p)
+{
+  napoly w, a;
+
+  if (p==NULL) return NULL;
+#ifndef LONGALGNEW
+  a = w = (napoly)omAlloc0(napMonomSize);
+  memcpy4(a->e, p->e, naParsToCopy * SIZEOF_PARAMETER);
+  w->ko = nacMap(p->ko);
+#else /* LONGALGNEW */
+  a = w = (napoly)p_Init(nacRing);
+  int i;
+  for(i=1;i<=naParsToCopy;i++)
+    napSetExp(a,i,napGetExpFrom(p,i,napMapRing));
+  p_Setm(a,nacRing);
+  napGetCoeff(w) = nacMap(napGetCoeff(p));
+#endif /* LONGALGNEW */
+  loop
+  {
+    napIter(p);
+    if (p==NULL) break;
+#ifndef LONGALGNEW
+    a->ne = (napoly)omAlloc0(napMonomSize);
+    a = a->ne;
+    memcpy4(a->e, p->e, naParsToCopy * SIZEOF_PARAMETER);
+#else /* LONGALGNEW */
+    napNext(a) = (napoly)p_Init(nacRing);
+    napIter(a);
+    for(i=1;i<=naParsToCopy;i++)
+      napSetExp(a,i,napGetExpFrom(p,i,napMapRing));
+    p_Setm(a,nacRing);
+#endif /* LONGALGNEW */
+    napGetCoeff(a) = nacMap(napGetCoeff(p));
+  }
+  napNext(a) = NULL;
+  return w;
+}
+
+/*2
+* map _(a) -> _(b)
+*/
+number naMapQaQb(number c)
+{
+  if (c==NULL) return NULL;
+  lnumber erg= (lnumber)omAlloc0Bin(rnumber_bin);
+  lnumber src =(lnumber)c;
+  erg->s=src->s;
+  erg->z=napMap(src->z);
+  erg->n=napMap(src->n);
+  if (naMinimalPoly!=NULL)
+  {
+    if (napGetExp(erg->z,1) >= napGetExp(naMinimalPoly,1))
+    {
+      erg->z = napRemainder(erg->z, naMinimalPoly);
+      if (erg->z==NULL)
+      {
+        number t_erg=(number)erg;
+        naDelete(&t_erg,currRing);
+        return (number)NULL;
+      }
+    }
+    if (erg->n!=NULL)
+    {
+      if (napGetExp(erg->n,1) >= napGetExp(naMinimalPoly,1))
+        erg->n = napRemainder(erg->n, naMinimalPoly);
+#ifndef LONGALGNEW
+      if ((napDeg(erg->n)==0) && nacIsOne(erg->n->ko))
+#else /* LONGALGNEW */
+      if ((napIsConstant(erg->n)) && nacIsOne(napGetCoeff(erg->n)))
+#endif /* LONGALGNEW */
+        napDelete(&(erg->n));
+    }
+  }
+  return (number)erg;
+}
+
+nMapFunc naSetMap(ring src, ring dst)
+{
+  if (rField_is_Q_a(dst)) /* -> Q(a) */
+  {
+    if (rField_is_Q(src))
+    {
+      return naMap00;   /*Q -> Q(a)*/
+    }
+    if (rField_is_Zp(src))
+    {
+      naPrimeM = rChar(src);
+      return naMapP0;  /* Z/p -> Q(a)*/
+    }
+    if (rField_is_Q_a(src))
+    {
+      int i;
+      naParsToCopy=0;
+      for(i=0;i<rPar(src);i++)
+      {
+        if ((i>=rPar(dst))
+        ||(strcmp(src->parameter[i],dst->parameter[i])!=0))
+           return NULL;
+        naParsToCopy++;
+      }
+#ifdef LONGALGNEW
+      napMapRing=src;
+#endif /* LONGALGNEW */
+      nacMap=nacCopy;
+      return naMapQaQb;   /* Q(a) -> Q(a) */
+    }
+  }
+  /*-----------------------------------------------------*/
+  if (rField_is_Zp_a(dst)) /* -> Z/p(a) */
+  {
+    if (rField_is_Q(src))
+    {
+      return naMap0P;   /*Q -> Z/p(a)*/
+    }
+    if (rField_is_Zp(src))
+    {
+      int c=rChar(src);
+      if (c==npPrimeM)
+      {
+        return naMapPP;  /* Z/p -> Z/p(a)*/
+      }
+      else
+      {
+        naPrimeM = c;
+        return naMapPP1;  /* Z/p' -> Z/p(a)*/
+      }
+    }
+    if (rField_is_Zp_a(src))
+    {
+      if (rChar(src)==rChar(dst))
+      {
+        nacMap=nacCopy;
+      }
+      else
+      {
+        npMapPrime=rChar(src);
+        nacMap = npMapP;
+      }
+      int i;
+      naParsToCopy=0;
+      for(i=0;i<rPar(src);i++)
+      {
+        if ((i>=rPar(dst))
+        ||(strcmp(src->parameter[i],dst->parameter[i])!=0))
+           return NULL;
+        naParsToCopy++;
+      }
+#ifdef LONGALGNEW
+      napMapRing=src;
+#endif /* LONGALGNEW */
+      return naMapQaQb;   /* Z/p(a),Z/p'(a) -> Z/p(b)*/
+    }
+  }
+  return NULL;      /* default */
+}
+
+/*2
+* convert a napoly number into a poly
+*/
+poly naPermNumber(number z, int * par_perm, int P, ring r)
+{
+  if (z==NULL) return NULL;
+  poly res=NULL;
+  poly p;
+  napoly za=((lnumber)z)->z;
+  nMapFunc nMap=NULL;
+  if (currRing->parameter!=NULL)
+    nMap=currRing->algring->cf->cfSetMap(r->algring, nacRing);
+  else
+    nMap=currRing->cf->cfSetMap(r->algring, currRing);
+  if (nMap==NULL) return NULL; /* emergency exit only */
+  do
+  {
+    p = pInit();
+    pNext(p)=NULL;
+    nNew(&pGetCoeff(p));
+    int i;
+    for(i=pVariables;i;i--)
+       pSetExp(p,i, 0);
+    pSetComp(p, 0);
+    napoly pa=NULL;
+    if (currRing->parameter!=NULL)
+    {
+      assume(r->algring!=NULL);
+      pGetCoeff(p)=(number)omAlloc0Bin(rnumber_bin);
+      ((lnumber)pGetCoeff(p))->s=2;
+      ((lnumber)pGetCoeff(p))->z=napInitz(nMap(napGetCoeff(za)));
+      pa=((lnumber)pGetCoeff(p))->z;
+    }
+    else
+    {
+      pGetCoeff(p)=nMap(napGetCoeff(za));
+    }
+    for(i=0;i<P;i++)
+    {
+      if(napGetExpFrom(za,i+1,r)!=0)
+      {
+        if(par_perm==NULL)
+        {
+          if ((rPar(currRing)>=i) && (pa!=NULL))
+	  {
+            napSetExp(pa,i+1,napGetExpFrom(za,i+1,r));
+            p_Setm(pa,nacRing);
+          }
+          else
+          {
+            pDelete(&p);
+            break;
+          }
+        }
+        else if(par_perm[i]>0)
+          pSetExp(p,par_perm[i],napGetExpFrom(za,i+1,r));
+        else if((par_perm[i]<0)&&(pa!=NULL))
+	{
+          napSetExp(pa,-par_perm[i], napGetExpFrom(za,i+1,r));
+          p_Setm(pa,nacRing);
+	}
+        else
+        {
+          pDelete(&p);
+          break;
+        }
+      }
+    }
+    if (p!=NULL)
+    {
+      pSetm(p);
+      pTest(p);
+      res=pAdd(res,p);
+    }
+    napIter(za);
+  }
+  while (za!=NULL);
+  pTest(res);
+  return res;
+}
+
+number   naGetDenom(number &n, const ring r)
+{
+  if (r==currRing) naNormalize(n);
+  lnumber x=(lnumber)n;
+  if (x->n!=NULL)
+  {
+    lnumber rr=(lnumber)omAlloc0Bin(rnumber_bin);
+    rr->z=nap_Copy(naGetDenom0(x),r);
+    rr->s = 2;
+    return (number)rr;
+  }
+  return r->cf->nInit(1);
+}
+
+#ifdef LDEBUG
+BOOLEAN naDBTest(number a, char *f,int l)
+{
+  lnumber x=(lnumber)a;
+  if (x == NULL)
+    return TRUE;
+  omCheckAddrSize(a, sizeof(snumber));
+  napoly p = x->z;
+  if (p==NULL)
+  {
+    Print("0/* in %s:%d\n",f,l);
+    return FALSE;
+  }
+  while(p!=NULL)
+  {
+    if ((naIsChar0 && nlIsZero(napGetCoeff(p)))
+    || ((!naIsChar0) && npIsZero(napGetCoeff(p))))
+    {
+      Print("coeff 0 in %s:%d\n",f,l);
+      return FALSE;
+    }
+    if((naMinimalPoly!=NULL)&&(napGetExp(p,1)>napGetExp(naMinimalPoly,1))
+    &&(p!=naMinimalPoly))
+    {
+      Print("deg>minpoly in %s:%d\n",f,l);
+      return FALSE;
+    }
+    //if (naIsChar0 && (((int)p->ko &3) == 0) && (p->ko->s==0) && (x->s==2))
+    //{
+    //  Print("normalized with non-normal coeffs in %s:%d\n",f,l);
+    //  return FALSE;
+    //}
+    if (naIsChar0 && !(nlDBTest(napGetCoeff(p),f,l)))
+      return FALSE;
+    napIter(p);
+  }
+  p = naGetDenom0(x);
+  while(p!=NULL)
+  {
+    if (naIsChar0 && !(nlDBTest(napGetCoeff(p),f,l)))
+      return FALSE;
+    napIter(p);
+  }
+  return TRUE;
+}
+#endif
+
Index: kernel/longalg.h
===================================================================
--- kernel/longalg.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/longalg.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,135 @@
+#ifndef LONGALG_H
+#define LONGALG_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: longalg.h,v 1.1.1.1 2003-10-06 12:15:57 Singular Exp $ */
+/*
+* ABSTRACT:   algebraic numbers
+*/
+#include "structs.h"
+#include "longrat.h"
+#include "polys-impl.h"
+
+struct slnumber;
+typedef struct slnumber * lnumber;
+
+#ifndef LONGALGNEW
+//make parameter type same as exponent type
+#define PARAMETER_TYPE short
+#define SIZEOF_PARAMETER SIZEOF_SHORT
+
+struct reca
+{
+  napoly ne;
+  number ko;
+  PARAMETER_TYPE e[1];
+};
+#endif /* not LONGALGNEW */
+
+struct slnumber
+{
+  napoly z;
+  napoly n;
+  BOOLEAN s;
+};
+
+extern int naNumbOfPar;             /* maximal number of parameters */
+extern napoly naMinimalPoly;
+#ifndef LONGALGNEW
+extern char **naParNames;
+extern int napMonomSize;
+#endif /* LONGALGNEW */
+
+void naSetChar(int p, ring r);
+#ifndef LONGALGNEW
+#define napAddExp(P,I,E)  ((P)->e[I-1]+=(E))
+#define napLength(p)      pLength((poly)p)
+napoly napNeg(napoly a);
+#endif /* LONGALGNEW */
+void    naDelete (number *p, const ring r);
+number  naInit(int i);                              /* z := i */
+number  naPar(int i);                               /* z := par(i) */
+int     naParDeg(number n);                         /* i := deg(n) */
+int     naSize(number n);                           /* size desc. */
+int     naInt(number &n);
+void    naNumberToInt(number n, int *i);
+void    naNew(number *z);
+BOOLEAN naIsZero(number za);                         /* za = 0 ? */
+BOOLEAN naIsOne(number  za);                         /* za = 1 ? */
+BOOLEAN naIsMOne(number  za);                        /* za = -1 ? */
+BOOLEAN naEqual(number a, number b);                  /* a = b ? */
+BOOLEAN naGreater(number a, number b);                  /* dummy */
+number  naNeg(number za);                           /* za := - za */
+number  naInvers(number a);
+BOOLEAN naGreaterZero(number a);
+void    naPower(number x, int exp, number *lo);
+BOOLEAN naGreaterZero(number a);
+number  naCopy(number p);                              /* erg:= p */
+number  na_Copy(number p, const ring r);               /* erg:= p */
+number  naAdd(number la, number li);               /* lu := la+li */
+number  naMult(number la, number li);              /* lo := la*li */
+number  naDiv(number la, number li);               /* lo := la/li */
+number  naIntDiv(number la, number li);            /* lo := la/li */
+//number  naIntMod(number la, number li);            /* lo := la/li */
+number  naSub(number la, number li);               /* lu := la-li */
+void    naNormalize(number &p);
+number  naGcd(number a, number b, const ring r);
+number  naLcm(number a, number b, const ring r);
+char *  naRead(char * s, number * p);
+void    naWrite(number &p);
+char *  naName(number n);
+nMapFunc naSetMap(ring src, ring dst);
+#ifdef LDEBUG
+BOOLEAN naDBTest(number a, char *f,int l);
+#endif
+
+void    naSetIdeal(ideal I);
+
+// external access to the interna
+#ifndef LONGALGNEW
+#define RECA_SIZE (sizeof(napoly)+sizeof(number))
+napoly napAdd(napoly p1, napoly p2);
+void napDelete(napoly *p);
+void nap_Delete(napoly *p, ring r);
+#endif /* not LONGALGNEW */
+poly naPermNumber(number z, int * par_perm, int P, ring r);
+#ifndef LONGALGNEW
+#define napVariables naNumbOfPar
+#define napNext(p) (p->ne)
+#define napIter(p) ((p) = (p)->ne)
+#define napGetCoeff(p) (p->ko)
+#define napGetExp(p,i) ((p)->e[(i)-1])
+#define napGetExpFrom(p,i,r) ((p)->e[(i)-1])
+#define napSetExp(p,i,ee) ((p)->e[(i)-1]=ee)
+#define napNew() ((napoly)omAlloc0(napMonomSize))
+#define nanumber lnumber
+#define naGetNom0(na)  (((nanumber)(na))->z)
+#define naGetDenom0(na)  (((nanumber)(na))->n)
+#else /* LONGALGNEW */
+#define napAddExp(p,i,e)       (p_AddExp(p,i,e,currRing->algring))
+#define napLength(p)           pLength(p)
+#define napNeg(p)              (p_Neg(p,currRing->algring))
+#define napVariables           naNumbOfPar
+#define napNext(p)             pNext(p)
+#define napIter(p)             pIter(p)
+#define napGetCoeff(p)         pGetCoeff(p)
+#define napGetExp(p,i)         (p_GetExp(p,i,currRing->algring))
+#define napGetExpFrom(p,i,r)   (p_GetExp(p,i,r->algring))
+#define napSetExp(p,i,e)       (p_SetExp(p,i,e,currRing->algring))
+#define napDelete(p)           p_Delete(p, currRing->algring)
+#define nap_Delete(p,r)        p_Delete(p, (r)->algring)
+#define napNew()               (p_Init(currRing->algring))
+#define napAdd(p1,p2)          (p_Add_q(p1,p2,currRing->algring))
+#define nanumber               lnumber
+#define naGetNom0(na)          (((nanumber)(na))->z)
+#define naGetDenom0(na)        (((nanumber)(na))->n)
+#endif /* LONGALGNEW */
+extern number   (*nacCopy)(number a);
+extern BOOLEAN  (*nacIsZero)(number a);
+extern number   (*nacInit)(int i);
+extern void     (*nacNormalize)(number &a);
+extern void napWrite(napoly l);
+extern number   naGetDenom(number &n, const ring r);
+#endif
+
Index: kernel/longrat.cc
===================================================================
--- kernel/longrat.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/longrat.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,2455 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: longrat.cc,v 1.1.1.1 2003-10-06 12:15:54 Singular Exp $ */
+/*
+* ABSTRACT: computation with long rational numbers (Hubert Grassmann)
+*/
+
+#ifndef LONGRAT_CC
+#define LONGRAT_CC
+
+#include <string.h>
+#include <float.h>
+#include "mod2.h"
+#include "structs.h"
+#include "omalloc.h"
+#include "febase.h"
+#include "numbers.h"
+#include "modulop.h"
+#include "ring.h"
+#include "shortfl.h"
+#include "mpr_complex.h"
+#include "longrat.h"
+
+
+#ifndef BYTES_PER_MP_LIMB
+#define BYTES_PER_MP_LIMB sizeof(mp_limb_t)
+#endif
+
+/*-----------------------------------------------------------------*/
+/*3
+* parameter s in number:
+* 0 (or FALSE): not normalised rational
+* 1 (or TRUE):  normalised rational
+* 3          :  integer with n==NULL
+*/
+/*3
+**  'SR_INT' is the type of those integers small enough to fit into  29  bits.
+**  Therefor the value range of this small integers is: $-2^{28}...2^{28}-1$.
+**
+**  Small integers are represented by an immediate integer handle, containing
+**  the value instead of pointing  to  it,  which  has  the  following  form:
+**
+**      +-------+-------+-------+-------+- - - -+-------+-------+-------+
+**      | guard | sign  | bit   | bit   |       | bit   | tag   | tag   |
+**      | bit   | bit   | 27    | 26    |       | 0     | 0     | 1     |
+**      +-------+-------+-------+-------+- - - -+-------+-------+-------+
+**
+**  Immediate integers handles carry the tag 'SR_INT', i.e. the last bit is 1.
+**  This distuingishes immediate integers from other handles which  point  to
+**  structures aligned on 4 byte boundaries and therefor have last bit  zero.
+**  (The second bit is reserved as tag to allow extensions of  this  scheme.)
+**  Using immediates as pointers and dereferencing them gives address errors.
+**
+**  To aid overflow check the most significant two bits must always be equal,
+**  that is to say that the sign bit of immediate integers has a  guard  bit.
+**
+**  The macros 'INT_TO_SR' and 'SR_TO_INT' should be used to convert  between
+**  a small integer value and its representation as immediate integer handle.
+**
+**  Large integers and rationals are represented by z and n
+**  where n may be undefined (if s==3)
+**  NULL represents only deleted values
+*/
+#define SR_HDL(A) ((long)(A))
+/*#define SR_INT    1*/
+/*#define INT_TO_SR(INT)  ((number) (((long)INT << 2) + SR_INT))*/
+// #define SR_TO_INT(SR)   (((long)SR) >> 2)
+
+#define MP_SMALL 1
+//#define mpz_isNeg(A) (mpz_cmp_si(A,(long)0)<0)
+#define mpz_isNeg(A) ((A)->_mp_size<0)
+#define mpz_limb_size(A) ((A)->_mp_size)
+#define mpz_limb_d(A) ((A)->_mp_d)
+#define MPZ_DIV(A,B,C) mpz_tdiv_q((A),(B),(C))
+#ifdef HAVE_SMALLGMP
+#define MPZ_EXACTDIV(A,B,C) mpz_tdiv_q((A),(B),(C))
+#else
+#define MPZ_EXACTDIV(A,B,C) mpz_divexact((A),(B),(C))
+#endif
+
+#ifdef LDEBUG
+#define nlTest(a) nlDBTest(a,__FILE__,__LINE__)
+BOOLEAN nlDBTest(number a, char *f,int l);
+#else
+#define nlTest(a) ((void)0)
+#endif
+
+
+/***************************************************************
+ *
+ * Routines which are never inlined by p_Numbers.h
+ *
+ *******************************************************************/
+#ifndef P_NUMBERS_H
+
+omBin rnumber_bin = omGetSpecBin(sizeof(snumber));
+
+number nlOne=nlInit(1);
+
+#if (__GNU_MP_VERSION*10+__GNU_MP_VERSION_MINOR < 31)
+void mpz_mul_si (mpz_ptr r, mpz_srcptr s, long int si)
+{
+  if (si>=0)
+    mpz_mul_ui(r,s,si);
+  else
+  {
+    mpz_mul_ui(r,s,-si);
+    mpz_neg(r,r);
+  }
+}
+#endif
+
+static int nlPrimeM;
+static number nlMapP(number from)
+{
+  number to;
+  int save=npPrimeM;
+  npPrimeM=nlPrimeM;
+  to = nlInit(npInt(from));
+  npPrimeM=save;
+  return to;
+}
+
+static number nlMapLongR(number from);
+static number nlMapR(number from);
+
+nMapFunc nlSetMap(ring src, ring dst)
+{
+  if (rField_is_Q(src))
+  {
+    return nlCopy;
+  }
+  if (rField_is_Zp(src))
+  {
+    nlPrimeM=rChar(src);
+    return nlMapP;
+  }
+  if (rField_is_R(src))
+  {
+    return nlMapR;
+  }
+  if (rField_is_long_R(src))
+  {
+    return nlMapLongR; /* long R -> Q */
+  }
+  return NULL;
+}
+
+#ifdef LDEBUG
+BOOLEAN nlDBTest(number a, char *f,int l)
+{
+  if (a==NULL)
+  {
+    Print("!!longrat: NULL in %s:%d\n",f,l);
+    return FALSE;
+  }
+  //if ((int)a==1) Print("!! 0x1 as number ? %s %d\n",f,l);
+  if ((((int)a)&3)==3)
+  {
+    Print(" !!longrat:ptr(3) in %s:%d\n",f,l);
+    return FALSE;
+  }
+  if ((((int)a)&3)==1)
+  {
+    if (((((int)a)<<1)>>1)!=((int)a))
+    {
+      Print(" !!longrat:arith:%x in %s:%d\n",(int)a, f,l);
+      return FALSE;
+    }
+    return TRUE;
+  }
+  omCheckIf(omCheckAddrSize(a,sizeof(*a)), return FALSE);
+  if (a->debug!=123456)
+  {
+    Print("!!longrat:debug:%d in %s:%d\n",a->debug,f,l);
+    a->debug=123456;
+    return FALSE;
+  }
+  if ((a->s<0)||(a->s>4))
+  {
+    Print("!!longrat:s=%d in %s:%d\n",a->s,f,l);
+    return FALSE;
+  }
+  omCheckAddrSize(a->z._mp_d,a->z._mp_alloc*BYTES_PER_MP_LIMB);
+  if (a->z._mp_alloc==0)
+    Print("!!longrat:z->alloc=0 in %s:%l\n",f,l);
+
+  if (a->s<2)
+  {
+    omCheckIf(omCheckAddrSize(a->n._mp_d,a->n._mp_alloc*BYTES_PER_MP_LIMB), return FALSE);
+    if (a->z._mp_alloc==0)
+      Print("!!longrat:n->alloc=0 in %s:%l\n",f,l);
+    if (mpz_cmp_si(&a->n,(long)1)==0)
+    {
+      Print("!!longrat:integer as rational in %s:%d\n",f,l);
+      return FALSE;
+    }
+    else if (mpz_isNeg(&a->n))
+    {
+      Print("!!longrat:div. by negative in %s:%d\n",f,l);
+      mpz_neg(&a->z,&a->z);
+      mpz_neg(&a->n,&a->n);
+      return FALSE;
+    }
+    return TRUE;
+  }
+  if (a->s==2)
+  {
+    Print("!!longrat:s=2 in %s:%d\n",f,l);
+    return FALSE;
+  }
+  if (mpz_size1(&a->z)>MP_SMALL) return TRUE;
+  int ui=(int)mpz_get_si(&a->z);
+  if ((((ui<<3)>>3)==ui)
+  && (mpz_cmp_si(&a->z,(long)ui)==0))
+  {
+    Print("!!longrat:im int %d in %s:%d\n",ui,f,l);
+    f=NULL;
+    return FALSE;
+  }
+  return TRUE;
+}
+#endif
+
+number nlRInit (int i);
+
+static number nlMapR(number from)
+{
+  double f=nrFloat(from);
+  if (f==0.0) return nlInit(0);
+  int f_sign=1;
+  if (f<0.0)
+  {
+    f_sign=-1;
+    f=-f;
+  }
+  int i=0;
+  mpz_t h1;
+  mpz_init_set_ui(h1,1);
+  while((FLT_RADIX*f) < DBL_MAX && i<DBL_MANT_DIG)
+  {
+    f*=FLT_RADIX;
+    mpz_mul_ui(h1,h1,FLT_RADIX);
+    i++;
+  }
+  number r=nlRInit(1);
+  mpz_set_d(&(r->z),f);
+  memcpy4(&(r->n),&h1,sizeof(h1));
+  r->s=0; /* not normalized */
+  nlNormalize(r);
+  return r;
+}
+
+static number nlMapLongR(number from)
+{
+  gmp_float *ff=(gmp_float*)from;
+  mpf_t *f=ff->_mpfp();
+  number res;
+  lint *dest,*ndest;
+  int size, i,negative;
+  int e,al,bl;
+  mp_ptr qp,dd,nn;
+
+  size = (*f)[0]._mp_size;
+  if (size == 0)
+    return nlInit(0);
+  if(size<0)
+  {
+    negative = 1;
+    size = -size;
+  }
+  else
+    negative = 0;
+
+  qp = (*f)[0]._mp_d;
+  while(qp[0]==0)
+  {
+    qp++;
+    size--;
+  }
+
+  e=(*f)[0]._mp_exp-size;
+  res = (number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+  res->debug=123456;
+#endif
+  dest = &(res->z);
+
+  if (e<0)
+  {
+    al = dest->_mp_size = size;
+    if (al<2) al = 2;
+    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
+    for (i=0;i<size;i++) dd[i] = qp[i];
+    bl = 1-e;
+    nn = (mp_ptr)omAlloc(sizeof(mp_limb_t)*bl);
+    nn[bl-1] = 1;
+    for (i=bl-2;i>=0;i--) nn[i] = 0;
+    ndest = &(res->n);
+    ndest->_mp_d = nn;
+    ndest->_mp_alloc = ndest->_mp_size = bl;
+    res->s = 0;
+  }
+  else
+  {
+    al = dest->_mp_size = size+e;
+    if (al<2) al = 2;
+    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
+    for (i=0;i<size;i++) dd[i+e] = qp[i];
+    for (i=0;i<e;i++) dd[i] = 0;
+    res->s = 3;
+  }
+
+  dest->_mp_d = dd;
+  dest->_mp_alloc = al;
+  if (negative) dest->_mp_size = -dest->_mp_size;
+
+  if (res->s==0)
+    nlNormalize(res);
+  else if (mpz_size1(&res->z)<=MP_SMALL)
+  {
+    // res is new, res->ref is 1
+    int ui=(int)mpz_get_si(&res->z);
+    if ((((ui<<3)>>3)==ui)
+       && (mpz_cmp_si(&res->z,(long)ui)==0))
+    {
+       mpz_clear(&res->z);
+#if defined(LDEBUG)
+       res->debug=654324;
+#endif
+       omFreeBin((ADDRESS)res, rnumber_bin);
+       return INT_TO_SR(ui);
+    }
+  }
+#if defined(LDEBUG)
+  nlTest(res);
+#endif
+  return res;
+}
+
+//static number nlMapLongR(number from)
+//{
+//  gmp_float *ff=(gmp_float*)from;
+//  const mpf_t *f=ff->mpfp();
+//  int f_size=ABS((*f)[0]._mp_size);
+//  if (f_size==0)
+//    return nlInit(0);
+//  int f_sign=1;
+//  number work=ngcCopy(from);
+//  if (!ngcGreaterZero(work))
+//  {
+//    f_sign=-1;
+//    work=ngcNeg(work);
+//  }
+//  int i=0;
+//  mpz_t h1;
+//  mpz_init_set_ui(h1,1);
+//  while((FLT_RADIX*f) < DBL_MAX && i<DBL_MANT_DIG)
+//  {
+//    f*=FLT_RADIX;
+//    mpz_mul_ui(h1,h1,FLT_RADIX);
+//    i++;
+//  }
+//  number r=nlRInit(1);
+//  mpz_set_d(&(r->z),f);
+//  memcpy4(&(r->n),&h1,sizeof(h1));
+//  r->s=0; /* not normalized */
+//  nlNormalize(r);
+//  return r;
+//
+//
+//  number r=nlRInit(1);
+//  int f_shift=f_size+(*f)[0]._mp_exp;
+//  if ( f_shift > 0)
+//  {
+//    r->s=0;
+//    mpz_init(&r->n);
+//    mpz_setbit(&r->n,f_shift*BYTES_PER_MP_LIMB*8);
+//    mpz_setbit(&r->z,f_size*BYTES_PER_MP_LIMB*8-1);
+//    // now r->z has enough space
+//    memcpy4(mpz_limb_d(&r->z),((*f)[0]._mp_d),f_size*BYTES_PER_MP_LIMB);
+//    nlNormalize(r);
+//  }
+//  else
+//  {
+//    r->s=3;
+//    if (f_shift==0)
+//    {
+//      mpz_setbit(&r->z,f_size*BYTES_PER_MP_LIMB*8-1);
+//      // now r->z has enough space
+//      memcpy4(mpz_limb_d(&r->z),((*f)[0]._mp_d),f_size*BYTES_PER_MP_LIMB);
+//    }
+//    else /* f_shift < 0 */
+//    {
+//      mpz_setbit(&r->z,(f_size-f_shift)*BYTES_PER_MP_LIMB*8-1);
+//      // now r->z has enough space
+//      memcpy4(mpz_limb_d(&r->z)-f_shift,((*f)[0]._mp_d),
+//        f_size*BYTES_PER_MP_LIMB);
+//    }
+//  }
+//  if ((*f)[0]._mp_size<0);
+//    r=nlNeg(r);
+//  return r;
+//}
+
+int nlSize(number a)
+{
+  if (a==INT_TO_SR(0))
+     return 0; /* rational 0*/
+  if (SR_HDL(a) & SR_INT)
+     return 1; /* immidiate int */
+  int s=a->z._mp_alloc;
+  if (a->s<2)
+  {
+    s+=a->n._mp_alloc;
+  }
+  return s;
+}
+
+/*2
+* convert number to int
+*/
+int nlInt(number &i)
+{
+#ifdef LDEBUG
+  nlTest(i);
+#endif
+  nlNormalize(i);
+  if (SR_HDL(i) &SR_INT) return SR_TO_INT(i);
+  if (i->s==3)
+  {
+    if(mpz_size1(&i->z)>MP_SMALL) return 0;
+    int ul=(int)mpz_get_si(&i->z);
+    if (mpz_cmp_si(&i->z,(long)ul)!=0) return 0;
+    return ul;
+  }
+  lint tmp;
+  int ul;
+  mpz_init(&tmp);
+  MPZ_DIV(&tmp,&i->z,&i->n);
+  if(mpz_size1(&tmp)>MP_SMALL) ul=0;
+  else
+  {
+    ul=(int)mpz_get_si(&tmp);
+    if (mpz_cmp_si(&tmp,(long)ul)!=0) ul=0;
+  }
+  mpz_clear(&tmp);
+  return ul;
+}
+
+/*
+* 1/a
+*/
+number nlInvers(number a)
+{
+#ifdef LDEBUG
+  nlTest(a);
+#endif
+  number n;
+  if (SR_HDL(a) & SR_INT)
+  {
+    if ((a==INT_TO_SR(1)) || (a==INT_TO_SR(-1)))
+    {
+      return a;
+    }
+    if (nlIsZero(a))
+    {
+      WerrorS("div. 1/0");
+      return INT_TO_SR(0);
+    }
+    n=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+    n->debug=123456;
+#endif
+    n->s=1;
+    if ((int)a>0)
+    {
+      mpz_init_set_si(&n->z,(long)1);
+      mpz_init_set_si(&n->n,(long)SR_TO_INT(a));
+    }
+    else
+    {
+      mpz_init_set_si(&n->z,(long)-1);
+      mpz_init_set_si(&n->n,(long)-SR_TO_INT(a));
+    }
+#ifdef LDEBUG
+    nlTest(n);
+#endif
+    return n;
+  }
+  n=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+  n->debug=123456;
+#endif
+  {
+    n->s=a->s;
+    mpz_init_set(&n->n,&a->z);
+    switch (a->s)
+    {
+      case 0:
+      case 1:
+              mpz_init_set(&n->z,&a->n);
+              if (mpz_isNeg(&n->n)) /* && n->s<2*/
+              {
+                mpz_neg(&n->z,&n->z);
+                mpz_neg(&n->n,&n->n);
+              }
+              if (mpz_cmp_si(&n->n,(long)1)==0)
+              {
+                mpz_clear(&n->n);
+                n->s=3;
+                if (mpz_size1(&n->z)<=MP_SMALL)
+                {
+                  int ui=(int)mpz_get_si(&n->z);
+                  if ((((ui<<3)>>3)==ui)
+                  && (mpz_cmp_si(&n->z,(long)ui)==0))
+                  {
+                    mpz_clear(&n->z);
+#if defined(LDEBUG)
+                    n->debug=654324;
+#endif
+                    omFreeBin((ADDRESS)n, rnumber_bin);
+                    n=INT_TO_SR(ui);
+                  }
+                }
+              }
+              break;
+      case 3:
+              n->s=1;
+              if (mpz_isNeg(&n->n)) /* && n->s<2*/
+              {
+                mpz_neg(&n->n,&n->n);
+                mpz_init_set_si(&n->z,(long)-1);
+              }
+              else
+              {
+                mpz_init_set_si(&n->z,(long)1);
+              }
+              break;
+    }
+  }
+#ifdef LDEBUG
+  nlTest(n);
+#endif
+  return n;
+}
+
+
+/*2
+* u := a / b in Z, if b | a (else undefined)
+*/
+number   nlExactDiv(number a, number b)
+{
+  if (b==INT_TO_SR(0))
+  {
+    WerrorS("div. by 0");
+    return INT_TO_SR(0);
+  }
+  if (a==INT_TO_SR(0))
+    return INT_TO_SR(0);
+  number u;
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    /* the small int -(1<<28) divided by -1 is the large int (1<<28)   */
+    if ((a==INT_TO_SR(-(1<<28)))&&(b==INT_TO_SR(-1)))
+    {
+      return nlRInit(1<<28);
+    }
+    int aa=SR_TO_INT(a);
+    int bb=SR_TO_INT(b);
+    return INT_TO_SR(aa/bb);
+  }
+  number bb=NULL;
+  if (SR_HDL(b) & SR_INT)
+  {
+    bb=nlRInit(SR_TO_INT(b));
+    b=bb;
+  }
+  u=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+  u->debug=123456;
+#endif
+  mpz_init(&u->z);
+  /* u=a/b */
+  u->s = 3;
+  MPZ_EXACTDIV(&u->z,&a->z,&b->z);
+  if (bb!=NULL)
+  {
+    mpz_clear(&bb->z);
+#if defined(LDEBUG)
+    bb->debug=654324;
+#endif
+    omFreeBin((ADDRESS)bb, rnumber_bin);
+  }
+  if (mpz_size1(&u->z)<=MP_SMALL)
+  {
+    int ui=(int)mpz_get_si(&u->z);
+    if ((((ui<<3)>>3)==ui)
+    && (mpz_cmp_si(&u->z,(long)ui)==0))
+    {
+      mpz_clear(&u->z);
+#if defined(LDEBUG)
+      u->debug=654324;
+#endif
+      omFreeBin((ADDRESS)u, rnumber_bin);
+      u=INT_TO_SR(ui);
+    }
+  }
+#ifdef LDEBUG
+  nlTest(u);
+#endif
+  return u;
+}
+
+/*2
+* u := a / b in Z
+*/
+number nlIntDiv (number a, number b)
+{
+  if (b==INT_TO_SR(0))
+  {
+    WerrorS("div. by 0");
+    return INT_TO_SR(0);
+  }
+  if (a==INT_TO_SR(0))
+    return INT_TO_SR(0);
+  number u;
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    /* the small int -(1<<28) divided by -1 is the large int (1<<28)   */
+    if ((a==INT_TO_SR(-(1<<28)))&&(b==INT_TO_SR(-1)))
+    {
+      return nlRInit(1<<28);
+    }
+    /* consider the signs of a and b:
+    *  + + -> u=a+b-1
+    *  + - -> u=a-b-1
+    *  - + -> u=a-b+1
+    *  - - -> u=a+b+1
+    */
+    int aa=SR_TO_INT(a);
+    int bb=SR_TO_INT(b);
+    if (aa>0)
+    {
+      if (bb>0)
+        return INT_TO_SR((aa+bb-1)/bb);
+      else
+        return INT_TO_SR((aa-bb-1)/bb);
+    }
+    else
+    {
+      if (bb>0)
+      {
+        return INT_TO_SR((aa-bb+1)/bb);
+      }
+      else
+      {
+        return INT_TO_SR((aa+bb+1)/bb);
+      }
+    }
+  }
+  if (SR_HDL(a) & SR_INT)
+  {
+    /* the small int -(1<<28) divided by 2^28 is 1   */
+    if (a==INT_TO_SR(-(1<<28)))
+    {
+      if(mpz_cmp_si(&b->z,(long)(1<<28))==0)
+      {
+        return INT_TO_SR(-1);
+      }
+    }
+    /* a is a small and b is a large int: -> 0 */
+    return INT_TO_SR(0);
+  }
+  number bb=NULL;
+  if (SR_HDL(b) & SR_INT)
+  {
+    bb=nlRInit(SR_TO_INT(b));
+    b=bb;
+  }
+  u=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+  u->debug=123456;
+#endif
+  mpz_init_set(&u->z,&a->z);
+  /* consider the signs of a and b:
+  *  + + -> u=a+b-1
+  *  + - -> u=a-b-1
+  *  - + -> u=a-b+1
+  *  - - -> u=a+b+1
+  */
+  if (mpz_isNeg(&a->z))
+  {
+    if (mpz_isNeg(&b->z))
+    {
+      mpz_add(&u->z,&u->z,&b->z);
+    }
+    else
+    {
+      mpz_sub(&u->z,&u->z,&b->z);
+    }
+    mpz_add_ui(&u->z,&u->z,1);
+  }
+  else
+  {
+    if (mpz_isNeg(&b->z))
+    {
+      mpz_sub(&u->z,&u->z,&b->z);
+    }
+    else
+    {
+      mpz_add(&u->z,&u->z,&b->z);
+    }
+    mpz_sub_ui(&u->z,&u->z,1);
+  }
+  /* u=u/b */
+  u->s = 3;
+  MPZ_DIV(&u->z,&u->z,&b->z);
+  if (bb!=NULL)
+  {
+    mpz_clear(&bb->z);
+#if defined(LDEBUG)
+    bb->debug=654324;
+#endif
+    omFreeBin((ADDRESS)bb, rnumber_bin);
+  }
+  if (mpz_size1(&u->z)<=MP_SMALL)
+  {
+    int ui=(int)mpz_get_si(&u->z);
+    if ((((ui<<3)>>3)==ui)
+    && (mpz_cmp_si(&u->z,(long)ui)==0))
+    {
+      mpz_clear(&u->z);
+#if defined(LDEBUG)
+      u->debug=654324;
+#endif
+      omFreeBin((ADDRESS)u, rnumber_bin);
+      u=INT_TO_SR(ui);
+    }
+  }
+#ifdef LDEBUG
+  nlTest(u);
+#endif
+  return u;
+}
+
+/*2
+* u := a mod b in Z, u>=0
+*/
+number nlIntMod (number a, number b)
+{
+  if (b==INT_TO_SR(0))
+  {
+    WerrorS("div. by 0");
+    return INT_TO_SR(0);
+  }
+  if (a==INT_TO_SR(0))
+    return INT_TO_SR(0);
+  number u;
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    if ((int)a>0)
+    {
+      if ((int)b>0)
+        return INT_TO_SR(SR_TO_INT(a)%SR_TO_INT(b));
+      else
+        return INT_TO_SR(SR_TO_INT(a)%(-SR_TO_INT(b)));
+    }
+    else
+    {
+      if ((int)b>0)
+      {
+        int i=(-SR_TO_INT(a))%SR_TO_INT(b);
+        if ( i != 0 ) i = (SR_TO_INT(b))-i;
+        return INT_TO_SR(i);
+      }
+      else
+      {
+        int i=(-SR_TO_INT(a))%(-SR_TO_INT(b));
+        if ( i != 0 ) i = (-SR_TO_INT(b))-i;
+        return INT_TO_SR(i);
+      }
+    }
+  }
+  if (SR_HDL(a) & SR_INT)
+  {
+    /* a is a small and b is a large int: -> a or (a+b) or (a-b) */
+    if ((int)a<0)
+    {
+      if (mpz_isNeg(&b->z))
+        return nlSub(a,b);
+      /*else*/
+        return nlAdd(a,b);
+    }
+    /*else*/
+      return a;
+  }
+  number bb=NULL;
+  if (SR_HDL(b) & SR_INT)
+  {
+    bb=nlRInit(SR_TO_INT(b));
+    b=bb;
+  }
+  u=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+  u->debug=123456;
+#endif
+  mpz_init(&u->z);
+  u->s = 3;
+  mpz_mod(&u->z,&a->z,&b->z);
+  if (bb!=NULL)
+  {
+    mpz_clear(&bb->z);
+#if defined(LDEBUG)
+    bb->debug=654324;
+#endif
+    omFreeBin((ADDRESS)bb, rnumber_bin);
+  }
+  if (mpz_isNeg(&u->z))
+  {
+    if (mpz_isNeg(&b->z))
+      mpz_sub(&u->z,&u->z,&b->z);
+    else
+      mpz_add(&u->z,&u->z,&b->z);
+  }
+  if (mpz_size1(&u->z)<=MP_SMALL)
+  {
+    int ui=(int)mpz_get_si(&u->z);
+    if ((((ui<<3)>>3)==ui)
+    && (mpz_cmp_si(&u->z,(long)ui)==0))
+    {
+      mpz_clear(&u->z);
+#if defined(LDEBUG)
+      u->debug=654324;
+#endif
+      omFreeBin((ADDRESS)u, rnumber_bin);
+      u=INT_TO_SR(ui);
+    }
+  }
+#ifdef LDEBUG
+  nlTest(u);
+#endif
+  return u;
+}
+
+/*2
+* u := a / b
+*/
+number nlDiv (number a, number b)
+{
+  number u;
+  if (nlIsZero(b))
+  {
+    WerrorS("div. by 0");
+    return INT_TO_SR(0);
+  }
+  u=(number)omAllocBin(rnumber_bin);
+  u->s=0;
+#if defined(LDEBUG)
+  u->debug=123456;
+#endif
+// ---------- short / short ------------------------------------
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    int i=SR_TO_INT(a);
+    int j=SR_TO_INT(b);
+    int r=i%j;
+    if (r==0)
+    {
+      omFreeBin((ADDRESS)u, rnumber_bin);
+      return INT_TO_SR(i/j);
+    }
+    mpz_init_set_si(&u->z,(long)i);
+    mpz_init_set_si(&u->n,(long)j);
+  }
+  else
+  {
+    mpz_init(&u->z);
+// ---------- short / long ------------------------------------
+    if (SR_HDL(a) & SR_INT)
+    {
+      // short a / (z/n) -> (a*n)/z
+      if (b->s<2)
+      {
+        mpz_mul_si(&u->z,&b->n,SR_TO_INT(a));
+      }
+      else
+      // short a / long z -> a/z
+      {
+        mpz_set_si(&u->z,SR_TO_INT(a));
+      }
+      if (mpz_cmp(&u->z,&b->z)==0)
+      {
+        mpz_clear(&u->z);
+        omFreeBin((ADDRESS)u, rnumber_bin);
+        return INT_TO_SR(1);
+      }
+      mpz_init_set(&u->n,&b->z);
+    }
+// ---------- long / short ------------------------------------
+    else if (SR_HDL(b) & SR_INT)
+    {
+      mpz_set(&u->z,&a->z);
+      // (z/n) / b -> z/(n*b)
+      if (a->s<2)
+      {
+        mpz_init_set(&u->n,&a->n);
+        if ((int)b>0)
+          mpz_mul_ui(&u->n,&u->n,SR_TO_INT(b));
+        else
+        {
+          mpz_mul_ui(&u->n,&u->n,-SR_TO_INT(b));
+          mpz_neg(&u->z,&u->z);
+        }
+      }
+      else
+      // long z / short b -> z/b
+      {
+        //mpz_set(&u->z,&a->z);
+        mpz_init_set_si(&u->n,SR_TO_INT(b));
+      }
+    }
+// ---------- long / long ------------------------------------
+    else
+    {
+      mpz_set(&u->z,&a->z);
+      mpz_init_set(&u->n,&b->z);
+      if (a->s<2) mpz_mul(&u->n,&u->n,&a->n);
+      if (b->s<2) mpz_mul(&u->z,&u->z,&b->n);
+    }
+  }
+  if (mpz_isNeg(&u->n))
+  {
+    mpz_neg(&u->z,&u->z);
+    mpz_neg(&u->n,&u->n);
+  }
+  if (mpz_cmp_si(&u->n,(long)1)==0)
+  {
+    mpz_clear(&u->n);
+    if (mpz_size1(&u->z)<=MP_SMALL)
+    {
+      int ui=(int)mpz_get_si(&u->z);
+      if ((((ui<<3)>>3)==ui)
+      && (mpz_cmp_si(&u->z,(long)ui)==0))
+      {
+        mpz_clear(&u->z);
+        omFreeBin((ADDRESS)u, rnumber_bin);
+        return INT_TO_SR(ui);
+      }
+    }
+    u->s=3;
+  }
+#ifdef LDEBUG
+  nlTest(u);
+#endif
+  return u;
+}
+
+/*2
+* u:= x ^ exp
+*/
+void nlPower (number x,int exp,number * u)
+{
+  if (!nlIsZero(x))
+  {
+#ifdef LDEBUG
+    nlTest(x);
+#endif
+    number aa=NULL;
+    if (SR_HDL(x) & SR_INT)
+    {
+      aa=nlRInit(SR_TO_INT(x));
+      x=aa;
+    }
+    *u=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+    (*u)->debug=123456;
+#endif
+    mpz_init(&(*u)->z);
+    mpz_pow_ui(&(*u)->z,&x->z,(unsigned long)exp);
+    if (x->s<2)
+    {
+      if (mpz_cmp_si(&x->n,(long)1)==0)
+      {
+        x->s=3;
+        mpz_clear(&x->n);
+      }
+      else
+      {
+        mpz_init(&(*u)->n);
+        mpz_pow_ui(&(*u)->n,&x->n,(unsigned long)exp);
+      }
+    }
+    (*u)->s = x->s;
+    if (((*u)->s==3) && (mpz_size1(&(*u)->z)<=MP_SMALL))
+    {
+      int ui=(int)mpz_get_si(&(*u)->z);
+      if ((((ui<<3)>>3)==ui)
+      && (mpz_cmp_si(&(*u)->z,(long)ui)==0))
+      {
+        mpz_clear(&(*u)->z);
+        omFreeBin((ADDRESS)*u, rnumber_bin);
+        *u=INT_TO_SR(ui);
+      }
+    }
+    if (aa!=NULL)
+    {
+      mpz_clear(&aa->z);
+      omFreeBin((ADDRESS)aa, rnumber_bin);
+    }
+  }
+  else
+    *u = INT_TO_SR(0);
+#ifdef LDEBUG
+  nlTest(*u);
+#endif
+}
+
+
+/*2
+* za >= 0 ?
+*/
+BOOLEAN nlGreaterZero (number a)
+{
+#ifdef LDEBUG
+  nlTest(a);
+#endif
+  if (SR_HDL(a) & SR_INT) return SR_HDL(a)>=0;
+  return (!mpz_isNeg(&a->z));
+}
+
+/*2
+* a > b ?
+*/
+BOOLEAN nlGreater (number a, number b)
+{
+#ifdef LDEBUG
+  nlTest(a);
+  nlTest(b);
+#endif
+  number r;
+  BOOLEAN rr;
+  r=nlSub(a,b);
+  rr=(!nlIsZero(r)) && (nlGreaterZero(r));
+  nlDelete(&r,currRing);
+  return rr;
+}
+
+/*2
+* a == -1 ?
+*/
+BOOLEAN nlIsMOne (number a)
+{
+#ifdef LDEBUG
+  if (a==NULL) return FALSE;
+  nlTest(a);
+#endif
+  if (SR_HDL(a) & SR_INT) return (a==INT_TO_SR(-1));
+  return FALSE;
+}
+
+/*2
+* result =gcd(a,b)
+*/
+number nlGcd(number a, number b, const ring r)
+{
+  number result;
+#ifdef LDEBUG
+  nlTest(a);
+  nlTest(b);
+#endif
+  //nlNormalize(a);
+  //nlNormalize(b);
+  if ((SR_HDL(a)==5)||(a==INT_TO_SR(-1))
+  ||  (SR_HDL(b)==5)||(b==INT_TO_SR(-1))) return INT_TO_SR(1);
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    int i=SR_TO_INT(a);
+    int j=SR_TO_INT(b);
+    if((i==0)||(j==0))
+      return INT_TO_SR(1);
+    int l;
+    i=ABS(i);
+    j=ABS(j);
+    do
+    {
+      l=i%j;
+      i=j;
+      j=l;
+    } while (l!=0);
+    return INT_TO_SR(i);
+  }
+  if (((!(SR_HDL(a) & SR_INT))&&(a->s<2))
+  ||  ((!(SR_HDL(b) & SR_INT))&&(b->s<2))) return INT_TO_SR(1);
+  result=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+  result->debug=123456;
+#endif
+  mpz_init(&result->z);
+  if (SR_HDL(a) & SR_INT)
+  {
+    mpz_gcd_ui(&result->z,&b->z,ABS(SR_TO_INT(a)));
+  }
+  else
+  if (SR_HDL(b) & SR_INT)
+  {
+    mpz_gcd_ui(&result->z,&a->z,ABS(SR_TO_INT(b)));
+  }
+  else
+  {
+    mpz_gcd(&result->z,&a->z,&b->z);
+  }
+  result->s = 3;
+  if (mpz_size1(&result->z)<=MP_SMALL)
+  {
+    int ui=(int)mpz_get_si(&result->z);
+    if ((((ui<<3)>>3)==ui)
+    && (mpz_cmp_si(&result->z,(long)ui)==0))
+    {
+      mpz_clear(&result->z);
+      omFreeBin((ADDRESS)result, rnumber_bin);
+      result=INT_TO_SR(ui);
+    }
+  }
+#ifdef LDEBUG
+  nlTest(result);
+#endif
+  return result;
+}
+
+/*2
+* simplify x
+*/
+void nlNormalize (number &x)
+{
+  if ((SR_HDL(x) & SR_INT) ||(x==NULL))
+    return;
+#ifdef LDEBUG
+  if (!nlTest(x)) return;
+#endif
+  if (x->s==3)
+  {
+    if (mpz_cmp_ui(&x->z,(long)0)==0)
+    {
+      nlDelete(&x,currRing);
+      x=nlInit(0);
+      return;
+    }
+    if (mpz_size1(&x->z)<=MP_SMALL)
+    {
+      int ui=(int)mpz_get_si(&x->z);
+      if ((((ui<<3)>>3)==ui)
+      && (mpz_cmp_si(&x->z,(long)ui)==0))
+      {
+        mpz_clear(&x->z);
+        omFreeBin((ADDRESS)x, rnumber_bin);
+        x=INT_TO_SR(ui);
+        return;
+      }
+    }
+  }
+  if (x->s==0)
+  {
+    BOOLEAN divided=FALSE;
+    MP_INT gcd;
+    mpz_init(&gcd);
+    mpz_gcd(&gcd,&x->z,&x->n);
+    x->s=1;
+    if (mpz_cmp_si(&gcd,(long)1)!=0)
+    {
+      MP_INT r;
+      mpz_init(&r);
+      MPZ_EXACTDIV(&r,&x->z,&gcd);
+      mpz_set(&x->z,&r);
+      MPZ_EXACTDIV(&r,&x->n,&gcd);
+      mpz_set(&x->n,&r);
+      mpz_clear(&r);
+      divided=TRUE;
+    }
+    mpz_clear(&gcd);
+    if (mpz_cmp_si(&x->n,(long)1)==0)
+    {
+      mpz_clear(&x->n);
+      if (mpz_size1(&x->z)<=MP_SMALL)
+      {
+        int ui=(int)mpz_get_si(&x->z);
+        if ((((ui<<3)>>3)==ui)
+        && (mpz_cmp_si(&x->z,(long)ui)==0))
+        {
+          mpz_clear(&x->z);
+#if defined(LDEBUG)
+          x->debug=654324;
+#endif
+          omFreeBin((ADDRESS)x, rnumber_bin);
+          x=INT_TO_SR(ui);
+          return;
+        }
+      }
+      x->s=3;
+    }
+    else if (divided)
+    {
+      _mpz_realloc(&x->n,mpz_size1(&x->n));
+    }
+    if (divided) _mpz_realloc(&x->z,mpz_size1(&x->z));
+  }
+#ifdef LDEBUG
+  nlTest(x);
+#endif
+}
+
+/*2
+* returns in result->z the lcm(a->z,b->n)
+*/
+number nlLcm(number a, number b, const ring r)
+{
+  number result;
+#ifdef LDEBUG
+  nlTest(a);
+  nlTest(b);
+#endif
+  if ((SR_HDL(b) & SR_INT)
+  || (b->s==3))
+  {
+    // b is 1/(b->n) => b->n is 1 => result is a
+    return nlCopy(a);
+  }
+  result=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+  result->debug=123456;
+#endif
+  result->s=3;
+  MP_INT gcd;
+  mpz_init(&gcd);
+  mpz_init(&result->z);
+  if (SR_HDL(a) & SR_INT)
+    mpz_gcd_ui(&gcd,&b->n,ABS(SR_TO_INT(a)));
+  else
+    mpz_gcd(&gcd,&a->z,&b->n);
+  if (mpz_cmp_si(&gcd,(long)1)!=0)
+  {
+    MP_INT bt;
+    mpz_init_set(&bt,&b->n);
+    MPZ_EXACTDIV(&bt,&bt,&gcd);
+    if (SR_HDL(a) & SR_INT)
+      mpz_mul_si(&result->z,&bt,SR_TO_INT(a));
+    else
+      mpz_mul(&result->z,&bt,&a->z);
+    mpz_clear(&bt);
+  }
+  else
+    if (SR_HDL(a) & SR_INT)
+      mpz_mul_si(&result->z,&b->n,SR_TO_INT(a));
+    else
+      mpz_mul(&result->z,&b->n,&a->z);
+  mpz_clear(&gcd);
+  if (mpz_size1(&result->z)<=MP_SMALL)
+  {
+    int ui=(int)mpz_get_si(&result->z);
+    if ((((ui<<3)>>3)==ui)
+    && (mpz_cmp_si(&result->z,(long)ui)==0))
+    {
+      mpz_clear(&result->z);
+      omFreeBin((ADDRESS)result, rnumber_bin);
+      return INT_TO_SR(ui);
+    }
+  }
+#ifdef LDEBUG
+  nlTest(result);
+#endif
+  return result;
+}
+
+int nlModP(number n, int p)
+{
+  if (SR_HDL(n) & SR_INT)
+  {
+    int i=SR_TO_INT(n);
+    if (i<0) return (p-((-i)%p));
+    return i%p;
+  }
+  int iz=mpz_mmod_ui(NULL,&n->z,(unsigned long)p);
+  if (n->s!=3)
+  {
+    int in=mpz_mmod_ui(NULL,&n->n,(unsigned long)p);
+    return (int)npDiv((number)iz,(number)in);
+  }
+  return iz;
+}
+
+/*2
+* acces to denominator, other 1 for integers
+*/
+number   nlGetDenom(number &n, const ring r)
+{
+  if (!(SR_HDL(n) & SR_INT))
+  {
+    if (n->s==0)
+    {
+      nlNormalize(n);
+    }
+    if (!(SR_HDL(n) & SR_INT))
+    {
+      if (n->s!=3)
+      {
+        number u=(number)omAllocBin(rnumber_bin);
+        u->s=3;
+#if defined(LDEBUG)
+        u->debug=123456;
+#endif
+        mpz_init_set(&u->z,&n->n);
+        {
+          int ui=(int)mpz_get_si(&u->z);
+          if ((((ui<<3)>>3)==ui)
+          && (mpz_cmp_si(&u->z,(long)ui)==0))
+          {
+            mpz_clear(&u->z);
+            omFreeBin((ADDRESS)u, rnumber_bin);
+            return INT_TO_SR(ui);
+          }
+        }
+        return u;
+      }
+    }
+  }
+  return INT_TO_SR(1);
+}
+
+/*2
+* acces to Nominator, nlCopy(n) for integers
+*/
+number   nlGetNom(number &n, const ring r)
+{
+  if (!(SR_HDL(n) & SR_INT))
+  {
+    if (n->s==0)
+    {
+      nlNormalize(n);
+    }
+    if (!(SR_HDL(n) & SR_INT))
+    {
+      number u=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+      u->debug=123456;
+#endif
+      u->s=3;
+      mpz_init_set(&u->z,&n->z);
+      if (n->s!=3)
+      {
+        int ui=(int)mpz_get_si(&u->z);
+        if ((((ui<<3)>>3)==ui)
+        && (mpz_cmp_si(&u->z,(long)ui)==0))
+        {
+          mpz_clear(&u->z);
+          omFreeBin((ADDRESS)u, rnumber_bin);
+          return INT_TO_SR(ui);
+        }
+      }
+      return u;
+    }
+  }
+  return n; // imm. int
+}
+
+/***************************************************************
+ *
+ * routines which are needed by Inline(d) routines
+ *
+ *******************************************************************/
+BOOLEAN _nlEqual_aNoImm_OR_bNoImm(number a, number b)
+{
+  assume(! (SR_HDL(a) & SR_HDL(b) & SR_INT));
+//  long - short
+  BOOLEAN bo;
+  if (SR_HDL(b) & SR_INT)
+  {
+    if (a->s!=0) return FALSE;
+    number n=b; b=a; a=n;
+  }
+//  short - long
+  if (SR_HDL(a) & SR_INT)
+  {
+    if (b->s!=0)
+      return FALSE;
+    if (((int)a > 0) && (mpz_isNeg(&b->z)))
+      return FALSE;
+    if (((int)a < 0) && (!mpz_isNeg(&b->z)))
+      return FALSE;
+    MP_INT  bb;
+    mpz_init_set(&bb,&b->n);
+    mpz_mul_si(&bb,&bb,(long)SR_TO_INT(a));
+    bo=(mpz_cmp(&bb,&b->z)==0);
+    mpz_clear(&bb);
+    return bo;
+  }
+// long - long
+  if (((a->s==1) && (b->s==3))
+  ||  ((b->s==1) && (a->s==3)))
+    return FALSE;
+  if (mpz_isNeg(&a->z)&&(!mpz_isNeg(&b->z)))
+    return FALSE;
+  if (mpz_isNeg(&b->z)&&(!mpz_isNeg(&a->z)))
+    return FALSE;
+  MP_INT  aa;
+  MP_INT  bb;
+  mpz_init_set(&aa,&a->z);
+  mpz_init_set(&bb,&b->z);
+  if (a->s<2) mpz_mul(&bb,&bb,&a->n);
+  if (b->s<2) mpz_mul(&aa,&aa,&b->n);
+  bo=(mpz_cmp(&aa,&bb)==0);
+  mpz_clear(&aa);
+  mpz_clear(&bb);
+  return bo;
+}
+
+// copy not immediate number a
+number _nlCopy_NoImm(number a)
+{
+  assume(!((SR_HDL(a) & SR_INT)||(a==NULL)));
+#ifdef LDEBUG
+  nlTest(a);
+#endif
+  number b=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+  b->debug=123456;
+#endif
+  switch (a->s)
+  {
+    case 0:
+    case 1:
+            mpz_init_set(&b->n,&a->n);
+    case 3:
+            mpz_init_set(&b->z,&a->z);
+            break;
+  }
+  b->s = a->s;
+#ifdef LDEBUG
+  nlTest(b);
+#endif
+  return b;
+}
+
+void _nlDelete_NoImm(number *a, const ring r)
+{
+  {
+    switch ((*a)->s)
+    {
+      case 0:
+      case 1:
+        mpz_clear(&(*a)->n);
+      case 3:
+        mpz_clear(&(*a)->z);
+#ifdef LDEBUG
+        (*a)->s=2;
+#endif
+    }
+    omFreeBin((ADDRESS) *a, rnumber_bin);
+  }
+}
+
+number _nlNeg_NoImm(number a)
+{
+  {
+    mpz_neg(&a->z,&a->z);
+    if ((a->s==3) && (mpz_size1(&a->z)<=MP_SMALL))
+    {
+      int ui=(int)mpz_get_si(&a->z);
+      if ((((ui<<3)>>3)==ui)
+        && (mpz_cmp_si(&a->z,(long)ui)==0))
+      {
+        mpz_clear(&a->z);
+        omFreeBin((ADDRESS)a, rnumber_bin);
+        a=INT_TO_SR(ui);
+      }
+    }
+  }
+#ifdef LDEBUG
+  nlTest(a);
+#endif
+  return a;
+}
+
+number _nlAdd_aNoImm_OR_bNoImm(number a, number b)
+{
+  number u=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+  u->debug=123456;
+#endif
+  mpz_init(&u->z);
+  if (SR_HDL(b) & SR_INT)
+  {
+    number x=a;
+    a=b;
+    b=x;
+  }
+  if (SR_HDL(a) & SR_INT)
+  {
+    switch (b->s)
+    {
+      case 0:
+      case 1:/* a:short, b:1 */
+      {
+        MP_INT x;
+        mpz_init(&x);
+        mpz_mul_si(&x,&b->n,SR_TO_INT(a));
+        mpz_add(&u->z,&b->z,&x);
+        mpz_clear(&x);
+        if (mpz_cmp_ui(&u->z,(long)0)==0)
+        {
+          mpz_clear(&u->z);
+          omFreeBin((ADDRESS)u, rnumber_bin);
+          return INT_TO_SR(0);
+        }
+        if (mpz_cmp(&u->z,&b->n)==0)
+        {
+          mpz_clear(&u->z);
+          omFreeBin((ADDRESS)u, rnumber_bin);
+          return INT_TO_SR(1);
+        }
+        mpz_init_set(&u->n,&b->n);
+        u->s = 0;
+        break;
+      }
+      case 3:
+      {
+        if ((int)a>0)
+          mpz_add_ui(&u->z,&b->z,SR_TO_INT(a));
+        else
+          mpz_sub_ui(&u->z,&b->z,-SR_TO_INT(a));
+        if (mpz_cmp_ui(&u->z,(long)0)==0)
+        {
+          mpz_clear(&u->z);
+          omFreeBin((ADDRESS)u, rnumber_bin);
+          return INT_TO_SR(0);
+        }
+        //u->s = 3;
+        if (mpz_size1(&u->z)<=MP_SMALL)
+        {
+          int ui=(int)mpz_get_si(&u->z);
+          if ((((ui<<3)>>3)==ui)
+          && (mpz_cmp_si(&u->z,(long)ui)==0))
+          {
+            mpz_clear(&u->z);
+            omFreeBin((ADDRESS)u, rnumber_bin);
+            return INT_TO_SR(ui);
+          }
+        }
+        u->s = 3;
+        break;
+      }
+    }
+  }
+  else
+  {
+    switch (a->s)
+    {
+      case 0:
+      case 1:
+      {
+        switch(b->s)
+        {
+          case 0:
+          case 1:
+          {
+            MP_INT x;
+            MP_INT y;
+            mpz_init(&x);
+            mpz_init(&y);
+            mpz_mul(&x,&b->z,&a->n);
+            mpz_mul(&y,&a->z,&b->n);
+            mpz_add(&u->z,&x,&y);
+            mpz_clear(&x);
+            mpz_clear(&y);
+            if (mpz_cmp_ui(&u->z,(long)0)==0)
+            {
+              mpz_clear(&u->z);
+              omFreeBin((ADDRESS)u, rnumber_bin);
+              return INT_TO_SR(0);
+            }
+            mpz_init(&u->n);
+            mpz_mul(&u->n,&a->n,&b->n);
+            if (mpz_cmp(&u->z,&u->n)==0)
+            {
+               mpz_clear(&u->z);
+               mpz_clear(&u->n);
+               omFreeBin((ADDRESS)u, rnumber_bin);
+               return INT_TO_SR(1);
+            }
+            u->s = 0;
+            break;
+          }
+          case 3: /* a:1 b:3 */
+          {
+            MP_INT x;
+            mpz_init(&x);
+            mpz_mul(&x,&b->z,&a->n);
+            mpz_add(&u->z,&a->z,&x);
+            mpz_clear(&x);
+            if (mpz_cmp_ui(&u->z,(long)0)==0)
+            {
+              mpz_clear(&u->z);
+              omFreeBin((ADDRESS)u, rnumber_bin);
+              return INT_TO_SR(0);
+            }
+            if (mpz_cmp(&u->z,&a->n)==0)
+            {
+              mpz_clear(&u->z);
+              omFreeBin((ADDRESS)u, rnumber_bin);
+              return INT_TO_SR(1);
+            }
+            mpz_init_set(&u->n,&a->n);
+            u->s = 0;
+            break;
+          }
+        } /*switch (b->s) */
+        break;
+      }
+      case 3:
+      {
+        switch(b->s)
+        {
+          case 0:
+          case 1:/* a:3, b:1 */
+          {
+            MP_INT x;
+            mpz_init(&x);
+            mpz_mul(&x,&a->z,&b->n);
+            mpz_add(&u->z,&b->z,&x);
+            mpz_clear(&x);
+            if (mpz_cmp_ui(&u->z,(long)0)==0)
+            {
+              mpz_clear(&u->z);
+              omFreeBin((ADDRESS)u, rnumber_bin);
+              return INT_TO_SR(0);
+            }
+            if (mpz_cmp(&u->z,&b->n)==0)
+            {
+              mpz_clear(&u->z);
+              omFreeBin((ADDRESS)u, rnumber_bin);
+              return INT_TO_SR(1);
+            }
+            mpz_init_set(&u->n,&b->n);
+            u->s = 0;
+            break;
+          }
+          case 3:
+          {
+            mpz_add(&u->z,&a->z,&b->z);
+            if (mpz_cmp_ui(&u->z,(long)0)==0)
+            {
+              mpz_clear(&u->z);
+              omFreeBin((ADDRESS)u, rnumber_bin);
+              return INT_TO_SR(0);
+            }
+            if (mpz_size1(&u->z)<=MP_SMALL)
+            {
+              int ui=(int)mpz_get_si(&u->z);
+              if ((((ui<<3)>>3)==ui)
+              && (mpz_cmp_si(&u->z,(long)ui)==0))
+              {
+                mpz_clear(&u->z);
+                omFreeBin((ADDRESS)u, rnumber_bin);
+                return INT_TO_SR(ui);
+              }
+            }
+            u->s = 3;
+            break;
+          }
+        }
+        break;
+      }
+    }
+  }
+#ifdef LDEBUG
+  nlTest(u);
+#endif
+  return u;
+}
+
+number _nlSub_aNoImm_OR_bNoImm(number a, number b)
+{
+  number u=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+  u->debug=123456;
+#endif
+  mpz_init(&u->z);
+  if (SR_HDL(a) & SR_INT)
+  {
+    switch (b->s)
+    {
+      case 0:
+      case 1:/* a:short, b:1 */
+      {
+        MP_INT x;
+        mpz_init(&x);
+        mpz_mul_si(&x,&b->n,SR_TO_INT(a));
+        mpz_sub(&u->z,&x,&b->z);
+        mpz_clear(&x);
+        if (mpz_cmp_ui(&u->z,(long)0)==0)
+        {
+          mpz_clear(&u->z);
+          omFreeBin((ADDRESS)u, rnumber_bin);
+          return INT_TO_SR(0);
+        }
+        if (mpz_cmp(&u->z,&b->n)==0)
+        {
+          mpz_clear(&u->z);
+          omFreeBin((ADDRESS)u, rnumber_bin);
+          return INT_TO_SR(1);
+        }
+        mpz_init_set(&u->n,&b->n);
+        u->s = 0;
+        break;
+      }
+      case 3:
+      {
+        if ((int)a>0)
+        {
+          mpz_sub_ui(&u->z,&b->z,SR_TO_INT(a));
+          mpz_neg(&u->z,&u->z);
+        }
+        else
+        {
+          mpz_add_ui(&u->z,&b->z,-SR_TO_INT(a));
+          mpz_neg(&u->z,&u->z);
+        }
+        if (mpz_cmp_ui(&u->z,(long)0)==0)
+        {
+          mpz_clear(&u->z);
+          omFreeBin((ADDRESS)u, rnumber_bin);
+          return INT_TO_SR(0);
+        }
+        if (mpz_size1(&u->z)<=MP_SMALL)
+        {
+          int ui=(int)mpz_get_si(&u->z);
+          if ((((ui<<3)>>3)==ui)
+          && (mpz_cmp_si(&u->z,(long)ui)==0))
+          {
+            mpz_clear(&u->z);
+            omFreeBin((ADDRESS)u, rnumber_bin);
+            return INT_TO_SR(ui);
+          }
+        }
+        u->s = 3;
+        break;
+      }
+    }
+  }
+  else if (SR_HDL(b) & SR_INT)
+  {
+    switch (a->s)
+    {
+      case 0:
+      case 1:/* b:short, a:1 */
+      {
+        MP_INT x;
+        mpz_init(&x);
+        mpz_mul_si(&x,&a->n,SR_TO_INT(b));
+        mpz_sub(&u->z,&a->z,&x);
+        mpz_clear(&x);
+        if (mpz_cmp_ui(&u->z,(long)0)==0)
+        {
+          mpz_clear(&u->z);
+          omFreeBin((ADDRESS)u, rnumber_bin);
+          return INT_TO_SR(0);
+        }
+        if (mpz_cmp(&u->z,&a->n)==0)
+        {
+          mpz_clear(&u->z);
+          omFreeBin((ADDRESS)u, rnumber_bin);
+          return INT_TO_SR(1);
+        }
+        mpz_init_set(&u->n,&a->n);
+        u->s = 0;
+        break;
+      }
+      case 3:
+      {
+        if ((int)b>0)
+        {
+          mpz_sub_ui(&u->z,&a->z,SR_TO_INT(b));
+        }
+        else
+        {
+          mpz_add_ui(&u->z,&a->z,-SR_TO_INT(b));
+        }
+        if (mpz_cmp_ui(&u->z,(long)0)==0)
+        {
+          mpz_clear(&u->z);
+          omFreeBin((ADDRESS)u, rnumber_bin);
+          return INT_TO_SR(0);
+        }
+        //u->s = 3;
+        if (mpz_size1(&u->z)<=MP_SMALL)
+        {
+          int ui=(int)mpz_get_si(&u->z);
+          if ((((ui<<3)>>3)==ui)
+          && (mpz_cmp_si(&u->z,(long)ui)==0))
+          {
+            mpz_clear(&u->z);
+            omFreeBin((ADDRESS)u, rnumber_bin);
+            return INT_TO_SR(ui);
+          }
+        }
+        u->s = 3;
+        break;
+      }
+    }
+  }
+  else
+  {
+    switch (a->s)
+    {
+      case 0:
+      case 1:
+      {
+        switch(b->s)
+        {
+          case 0:
+          case 1:
+          {
+            MP_INT x;
+            MP_INT y;
+            mpz_init(&x);
+            mpz_init(&y);
+            mpz_mul(&x,&b->z,&a->n);
+            mpz_mul(&y,&a->z,&b->n);
+            mpz_sub(&u->z,&y,&x);
+            mpz_clear(&x);
+            mpz_clear(&y);
+            if (mpz_cmp_ui(&u->z,(long)0)==0)
+            {
+              mpz_clear(&u->z);
+              omFreeBin((ADDRESS)u, rnumber_bin);
+              return INT_TO_SR(0);
+            }
+            mpz_init(&u->n);
+            mpz_mul(&u->n,&a->n,&b->n);
+            if (mpz_cmp(&u->z,&u->n)==0)
+            {
+              mpz_clear(&u->z);
+              mpz_clear(&u->n);
+              omFreeBin((ADDRESS)u, rnumber_bin);
+              return INT_TO_SR(1);
+            }
+            u->s = 0;
+            break;
+          }
+          case 3: /* a:1, b:3 */
+          {
+            MP_INT x;
+            mpz_init(&x);
+            mpz_mul(&x,&b->z,&a->n);
+            mpz_sub(&u->z,&a->z,&x);
+            mpz_clear(&x);
+            if (mpz_cmp_ui(&u->z,(long)0)==0)
+            {
+              mpz_clear(&u->z);
+              omFreeBin((ADDRESS)u, rnumber_bin);
+              return INT_TO_SR(0);
+            }
+            if (mpz_cmp(&u->z,&a->n)==0)
+            {
+              mpz_clear(&u->z);
+              omFreeBin((ADDRESS)u, rnumber_bin);
+              return INT_TO_SR(1);
+            }
+            mpz_init_set(&u->n,&a->n);
+            u->s = 0;
+            break;
+          }
+        }
+        break;
+      }
+      case 3:
+      {
+        switch(b->s)
+        {
+          case 0:
+          case 1: /* a:3, b:1 */
+          {
+            MP_INT x;
+            mpz_init(&x);
+            mpz_mul(&x,&a->z,&b->n);
+            mpz_sub(&u->z,&x,&b->z);
+            mpz_clear(&x);
+            if (mpz_cmp_ui(&u->z,(long)0)==0)
+            {
+              mpz_clear(&u->z);
+              omFreeBin((ADDRESS)u, rnumber_bin);
+              return INT_TO_SR(0);
+            }
+            if (mpz_cmp(&u->z,&b->n)==0)
+            {
+              mpz_clear(&u->z);
+              omFreeBin((ADDRESS)u, rnumber_bin);
+              return INT_TO_SR(1);
+            }
+            mpz_init_set(&u->n,&b->n);
+            u->s = 0;
+            break;
+          }
+          case 3: /* a:3 , b:3 */
+          {
+            mpz_sub(&u->z,&a->z,&b->z);
+            if (mpz_cmp_ui(&u->z,(long)0)==0)
+            {
+              mpz_clear(&u->z);
+              omFreeBin((ADDRESS)u, rnumber_bin);
+              return INT_TO_SR(0);
+            }
+            //u->s = 3;
+            if (mpz_size1(&u->z)<=MP_SMALL)
+            {
+              int ui=(int)mpz_get_si(&u->z);
+              if ((((ui<<3)>>3)==ui)
+              && (mpz_cmp_si(&u->z,(long)ui)==0))
+              {
+                mpz_clear(&u->z);
+                omFreeBin((ADDRESS)u, rnumber_bin);
+                return INT_TO_SR(ui);
+              }
+            }
+            u->s = 3;
+            break;
+          }
+        }
+        break;
+      }
+    }
+  }
+#ifdef LDEBUG
+  nlTest(u);
+#endif
+  return u;
+}
+
+// a and b are intermediate, but a*b not
+number _nlMult_aImm_bImm_rNoImm(number a, number b)
+{
+  number u=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+  u->debug=123456;
+#endif
+  u->s=3;
+  mpz_init_set_si(&u->z,(long)SR_TO_INT(a));
+  mpz_mul_si(&u->z,&u->z,(unsigned long)SR_TO_INT(b));
+#ifdef LDEBUG
+  nlTest(u);
+#endif
+  return u;
+}
+
+// a or b are not immediate
+number _nlMult_aNoImm_OR_bNoImm(number a, number b)
+{
+  assume(! (SR_HDL(a) & SR_HDL(b) & SR_INT));
+  number u=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+  u->debug=123456;
+#endif
+  mpz_init(&u->z);
+  if (SR_HDL(b) & SR_INT)
+  {
+    number x=a;
+    a=b;
+    b=x;
+  }
+  if (SR_HDL(a) & SR_INT)
+  {
+    u->s=b->s;
+    if (u->s==1) u->s=0;
+    if ((int)a>0)
+    {
+      mpz_mul_ui(&u->z,&b->z,(unsigned long)SR_TO_INT(a));
+    }
+    else
+    {
+      if (a==INT_TO_SR(-1))
+      {
+        mpz_set(&u->z,&b->z);
+        mpz_neg(&u->z,&u->z);
+        u->s=b->s;
+      }
+      else
+      {
+        mpz_mul_ui(&u->z,&b->z,(unsigned long)-SR_TO_INT(a));
+        mpz_neg(&u->z,&u->z);
+      }
+    }
+    if (u->s<2)
+    {
+      if (mpz_cmp(&u->z,&b->n)==0)
+      {
+        mpz_clear(&u->z);
+        omFreeBin((ADDRESS)u, rnumber_bin);
+        return INT_TO_SR(1);
+      }
+      mpz_init_set(&u->n,&b->n);
+    }
+    else //u->s==3
+    {
+      if (mpz_size1(&u->z)<=MP_SMALL)
+      {
+        int ui=(int)mpz_get_si(&u->z);
+        if ((((ui<<3)>>3)==ui)
+            && (mpz_cmp_si(&u->z,(long)ui)==0))
+        {
+          mpz_clear(&u->z);
+          omFreeBin((ADDRESS)u, rnumber_bin);
+          return INT_TO_SR(ui);
+        }
+      }
+    }
+  }
+  else
+  {
+    mpz_mul(&u->z,&a->z,&b->z);
+    u->s = 0;
+    if(a->s==3)
+    {
+      if(b->s==3)
+      {
+        u->s = 3;
+      }
+      else
+      {
+        if (mpz_cmp(&u->z,&b->n)==0)
+        {
+          mpz_clear(&u->z);
+          omFreeBin((ADDRESS)u, rnumber_bin);
+          return INT_TO_SR(1);
+        }
+        mpz_init_set(&u->n,&b->n);
+      }
+    }
+    else
+    {
+      if(b->s==3)
+      {
+        if (mpz_cmp(&u->z,&a->n)==0)
+        {
+          mpz_clear(&u->z);
+          omFreeBin((ADDRESS)u, rnumber_bin);
+          return INT_TO_SR(1);
+        }
+        mpz_init_set(&u->n,&a->n);
+      }
+      else
+      {
+        mpz_init(&u->n);
+        mpz_mul(&u->n,&a->n,&b->n);
+        if (mpz_cmp(&u->z,&u->n)==0)
+        {
+          mpz_clear(&u->z);
+          mpz_clear(&u->n);
+          omFreeBin((ADDRESS)u, rnumber_bin);
+          return INT_TO_SR(1);
+        }
+      }
+    }
+  }
+#ifdef LDEBUG
+  nlTest(u);
+#endif
+  return u;
+}
+
+/*2
+* z := i
+*/
+number nlRInit (int i)
+{
+  number z=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+  z->debug=123456;
+#endif
+  mpz_init_set_si(&z->z,(long)i);
+  z->s = 3;
+  return z;
+}
+
+/*2
+* z := i/j
+*/
+number nlInit2 (int i, int j)
+{
+  number z=(number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+  z->debug=123456;
+#endif
+  mpz_init_set_si(&z->z,(long)i);
+  mpz_init_set_si(&z->n,(long)j);
+  z->s = 0;
+  nlNormalize(z);
+  return z;
+}
+
+#else // DO_LINLINE
+
+// declare immedate routines
+number nlRInit (int i);
+BOOLEAN _nlEqual_aNoImm_OR_bNoImm(number a, number b);
+number  _nlCopy_NoImm(number a);
+void    _nlDelete_NoImm(number *a, const ring r);
+number  _nlNeg_NoImm(number a);
+number  _nlAdd_aNoImm_OR_bNoImm(number a, number b);
+number  _nlSub_aNoImm_OR_bNoImm(number a, number b);
+number  _nlMult_aNoImm_OR_bNoImm(number a, number b);
+number  _nlMult_aImm_bImm_rNoImm(number a, number b);
+
+#endif
+
+
+/***************************************************************
+ *
+ * Routines which might be inlined by p_Numbers.h
+ *
+ *******************************************************************/
+#if defined(DO_LINLINE) || !defined(P_NUMBERS_H)
+
+// routines which are always inlined/static
+
+/*2
+* a = b ?
+*/
+LINLINE BOOLEAN nlEqual (number a, number b)
+{
+#ifdef LDEBUG
+  nlTest(a);
+  nlTest(b);
+#endif
+// short - short
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT) return a==b;
+  return _nlEqual_aNoImm_OR_bNoImm(a, b);
+}
+
+
+LINLINE number nlInit (int i)
+{
+  number n;
+  if ( ((i << 3) >> 3) == i ) n=INT_TO_SR(i);
+  else                        n=nlRInit(i);
+#ifdef LDEBUG
+  nlTest(n);
+#endif
+  return n;
+}
+
+
+/*2
+* a == 1 ?
+*/
+LINLINE BOOLEAN nlIsOne (number a)
+{
+#ifdef LDEBUG
+  if (a==NULL) return FALSE;
+  nlTest(a);
+#endif
+  if (SR_HDL(a) & SR_INT) return (a==INT_TO_SR(1));
+  return FALSE;
+}
+
+LINLINE BOOLEAN nlIsZero (number a)
+{
+  return (a==INT_TO_SR(0));
+}
+
+/*2
+* copy a to b
+*/
+LINLINE number nlCopy(number a)
+{
+  if ((SR_HDL(a) & SR_INT)||(a==NULL))
+  {
+    return a;
+  }
+  return _nlCopy_NoImm(a);
+}
+
+
+LINLINE void nlNew (number * r)
+{
+  *r=NULL;
+}
+
+/*2
+* delete a
+*/
+LINLINE void nlDelete (number * a, const ring r)
+{
+  if (*a!=NULL)
+  {
+#ifdef LDEBUG
+    nlTest(*a);
+#endif
+    if ((SR_HDL(*a) & SR_INT)==0)
+    {
+      _nlDelete_NoImm(a,r);
+    }
+    *a=NULL;
+  }
+}
+
+/*2
+* za:= - za
+*/
+LINLINE number nlNeg (number a)
+{
+#ifdef LDEBUG
+  nlTest(a);
+#endif
+  if(SR_HDL(a) &SR_INT)
+  {
+    int r=SR_TO_INT(a);
+    if (r==(-(1<<28))) a=nlRInit(1<<28);
+    else               a=INT_TO_SR(-r);
+    return a;
+  }
+  return _nlNeg_NoImm(a);
+}
+
+/*2
+* u:= a + b
+*/
+LINLINE number nlAdd (number a, number b)
+{
+  number u;
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    int r=SR_HDL(a)+SR_HDL(b)-1;
+    if ( ((r << 1) >> 1) == r )
+      return (number)r;
+    else
+      return nlRInit(SR_TO_INT(r));
+  }
+  return _nlAdd_aNoImm_OR_bNoImm(a, b);
+}
+
+LINLINE number nlMult (number a, number b)
+{
+#ifdef LDEBUG
+  nlTest(a);
+  nlTest(b);
+#endif
+  if (a==INT_TO_SR(0)) return INT_TO_SR(0);
+  if (b==INT_TO_SR(0)) return INT_TO_SR(0);
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    int r=(SR_HDL(a)-1)*(SR_HDL(b)>>1);
+    if ((r/(SR_HDL(b)>>1))==(SR_HDL(a)-1))
+    {
+      number u=((number) ((r>>1)+SR_INT));
+      if (((SR_HDL(u)<<1)>>1)==SR_HDL(u)) return (u);
+      return nlRInit(SR_HDL(u)>>2);
+    }
+    return _nlMult_aImm_bImm_rNoImm(a, b);
+  }
+  return _nlMult_aNoImm_OR_bNoImm(a, b);
+}
+
+
+/*2
+* u:= a - b
+*/
+LINLINE number nlSub (number a, number b)
+{
+  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
+  {
+    int r=SR_HDL(a)-SR_HDL(b)+1;
+    if ( ((r << 1) >> 1) == r )
+    {
+      return (number)r;
+    }
+    else
+      return nlRInit(SR_TO_INT(r));
+  }
+  return _nlSub_aNoImm_OR_bNoImm(a, b);
+}
+
+#endif // DO_LINLINE
+
+#ifndef P_NUMBERS_H
+
+void nlInpGcd(number &a, number b, ring r)
+{
+  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
+  {
+    number n=nlGcd(a,b,r);
+    nlDelete(&a,r);
+    a=n;
+  }
+  else
+  {
+    mpz_gcd(&a->z,&a->z,&b->z);
+    if (mpz_size1(&a->z)<=MP_SMALL)
+    {
+      int ui=(int)mpz_get_si(&a->z);
+      if ((((ui<<3)>>3)==ui)
+      && (mpz_cmp_si(&a->z,(long)ui)==0))
+      {
+        mpz_clear(&a->z);
+        omFreeBin((ADDRESS)a, rnumber_bin);
+        a=INT_TO_SR(ui);
+      }
+    }
+  }
+}
+void nlInpIntDiv(number &a, number b, ring r)
+{
+  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
+  {
+    number n=nlIntDiv(a,b);
+    nlDelete(&a,r);
+    a=n;
+  }
+  else
+  {
+    if (mpz_isNeg(&a->z))
+    {
+      if (mpz_isNeg(&b->z))
+      {
+        mpz_add(&a->z,&a->z,&b->z);
+      }
+      else
+      {
+        mpz_sub(&a->z,&a->z,&b->z);
+      }
+      mpz_add_ui(&a->z,&a->z,1);
+    }
+    else
+    {
+      if (mpz_isNeg(&b->z))
+      {
+        mpz_sub(&a->z,&a->z,&b->z);
+      }
+      else
+      {
+        mpz_add(&a->z,&a->z,&b->z);
+      }
+      mpz_sub_ui(&a->z,&a->z,1);
+    }
+    MPZ_DIV(&a->z,&a->z,&b->z);
+    if (mpz_size1(&a->z)<=MP_SMALL)
+    {
+      int ui=(int)mpz_get_si(&a->z);
+      if ((((ui<<3)>>3)==ui)
+      && (mpz_cmp_si(&a->z,(long)ui)==0))
+      {
+        mpz_clear(&a->z);
+        omFreeBin((ADDRESS)a, rnumber_bin);
+        a=INT_TO_SR(ui);
+      }
+    }
+  }
+}
+void nlInpAdd(number &a, number b, ring r)
+{
+  // TODO
+  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
+  {
+    number n=nlGcd(a,b,r);
+    nlDelete(&a,r);
+    a=n;
+  }
+  else
+  {
+    mpz_gcd(&a->z,&a->z,&b->z);
+    if (mpz_size1(&a->z)<=MP_SMALL)
+    {
+      int ui=(int)mpz_get_si(&a->z);
+      if ((((ui<<3)>>3)==ui)
+      && (mpz_cmp_si(&a->z,(long)ui)==0))
+      {
+        mpz_clear(&a->z);
+        omFreeBin((ADDRESS)a, rnumber_bin);
+        a=INT_TO_SR(ui);
+      }
+    }
+  }
+}
+void nlInpMult(number &a, number b, ring r)
+{
+  if (((SR_HDL(b)|SR_HDL(a))&SR_INT)
+  )
+  {
+    number n=nlMult(a,b);
+    nlDelete(&a,r);
+    a=n;
+  }
+  else
+  {
+    mpz_mul(&a->z,&a->z,&b->z);
+    if (a->s==3)
+    {
+      if(b->s!=3)
+      {
+        mpz_init_set(&a->n,&b->n);
+        a->s=0;
+      }
+    }
+    else
+    {
+      if(b->s!=3)
+      {
+        mpz_mul(&a->n,&a->n,&b->n);
+      }
+      a->s=0;
+    }
+  }
+}
+
+#if 0
+number nlMod(number a, number b)
+{
+  if (((SR_HDL(b)&SR_HDL(a))&SR_INT)
+  {
+    int bi=SR_TO_INT(b);
+    int ai=SR_TO_INT(a);
+    int bb=ABS(bi);
+    int c=ai%bb;
+    if (c<0)  c+=bb;
+    return (INT_TO_SR(c));
+  }
+  number al;
+  number bl;
+  if (SR_HDL(a))&SR_INT)
+    al=nlRInit(SR_TO_INT(a));
+  else
+    al=nlCopy(a);
+  if (SR_HDL(b))&SR_INT)
+    bl=nlRInit(SR_TO_INT(b));
+  else
+    bl=nlCopy(b);
+  number r=nlRInit(0);
+  mpz_mod(r->z,al->z,bl->z);
+  nlDelete(&al);
+  nlDelete(&bl);
+  if (mpz_size1(&r->z)<=MP_SMALL)
+  {
+    int ui=(int)mpz_get_si(&r->z);
+    if ((((ui<<3)>>3)==ui)
+    && (mpz_cmp_si(&x->z,(long)ui)==0))
+    {
+      mpz_clear(&r->z);
+      omFreeBin((ADDRESS)r, rnumber_bin);
+      r=INT_TO_SR(ui);
+    }
+  }
+  return r;
+}
+#endif
+#endif // not P_NUMBERS_H
+#endif // LONGRAT_CC
Index: kernel/longrat.h
===================================================================
--- kernel/longrat.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/longrat.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,99 @@
+#ifndef LONGRAT_H
+#define LONGRAT_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: longrat.h,v 1.1.1.1 2003-10-06 12:15:57 Singular Exp $ */
+/*
+* ABSTRACT: computation with long rational numbers
+*/
+#include "structs.h"
+
+#include "si_gmp.h"
+
+typedef MP_INT lint;
+
+#define SR_INT    1
+#define INT_TO_SR(INT)  ((number) (((long)INT << 2) + SR_INT))
+#define SR_TO_INT(SR)   (((long)SR) >> 2)
+
+
+#define MP_SMALL 1
+
+#define mpz_size1(A) (ABS((A)->_mp_size))
+//#define mpz_size1(A) mpz_size(A)
+
+struct snumber;
+typedef struct snumber  *number;
+struct snumber
+{
+  lint z;
+  lint n;
+#if defined(LDEBUG)
+  int debug;
+#endif
+  BOOLEAN s;
+};
+
+// allow inlining only from p_Numbers.h and if ! LDEBUG
+
+#if defined(DO_LINLINE) && defined(P_NUMBERS_H) && !defined(LDEBUG)
+#define LINLINE static inline
+#else
+#define LINLINE
+#undef DO_LINLINE
+#endif // DO_LINLINE
+
+LINLINE BOOLEAN  nlEqual(number a, number b);
+LINLINE number   nlInit(int i);
+LINLINE BOOLEAN  nlIsOne(number a);
+LINLINE BOOLEAN  nlIsZero(number za);
+LINLINE number   nlCopy(number a);
+LINLINE void     nlNew(number *r);
+LINLINE void     nlDelete(number *a, const ring r);
+LINLINE number   nlNeg(number za);
+LINLINE number   nlAdd(number la, number li);
+LINLINE number   nlSub(number la, number li);
+LINLINE number   nlMult(number a, number b);
+
+number   nlInit2 (int i, int j);
+number   nlGcd(number a, number b, const ring r);
+number   nlLcm(number a, number b, const ring r);   /*special routine !*/
+BOOLEAN  nlGreater(number a, number b);
+BOOLEAN  nlIsMOne(number a);
+int      nlInt(number &n);
+BOOLEAN  nlGreaterZero(number za);
+number   nlInvers(number a);
+void     nlNormalize(number &x);
+number   nlDiv(number a, number b);
+number   nlExactDiv(number a, number b);
+number   nlIntDiv(number a, number b);
+number   nlIntMod(number a, number b);
+void     nlPower(number x, int exp, number *lu);
+char *   nlRead (char *s, number *a);
+void     nlWrite(number &a);
+int      nlModP(number n, int p);
+int      nlSize(number n);
+number   nlGetDenom(number &n, const ring r);
+number   nlGetNom(number &n, const ring r);
+#ifdef LDEBUG
+BOOLEAN  nlDBTest(number a, char *f, int l);
+#endif
+extern number nlOne;
+
+nMapFunc nlSetMap(ring src, ring dst);
+
+#ifndef OM_ALLOC_H
+struct omBin_s;
+#endif
+extern omBin_s* rnumber_bin;
+
+// in-place operations
+void nlInpGcd(number &a, number b, ring r);
+void nlInpIntDiv(number &a, number b, ring r);
+void nlInpAdd(number &a, number b, ring r);
+void nlInpMult(number &a, number b, ring r);
+
+#endif
+
+
Index: kernel/longrat0.cc
===================================================================
--- kernel/longrat0.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/longrat0.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,143 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: longrat0.cc,v 1.1.1.1 2003-10-06 12:15:54 Singular Exp $ */
+/*
+* ABSTRACT -
+* IO for long rational numbers (Hubert Grassmann)
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "mod2.h"
+#include "structs.h"
+#include "omalloc.h"
+#include "febase.h"
+#include "longrat.h"
+
+#define SR_HDL(A) ((long)(A))
+#define SR_INT    1
+#define INT_TO_SR(INT)  ((number) (((long)INT << 2) + SR_INT))
+#define SR_TO_INT(SR)   (((long)SR) >> 2)
+
+
+/*2
+* extracts a long integer from s, returns the rest
+*/
+char * nlEatLong(char *s, MP_INT *i)
+{
+  char * start=s;
+
+  while (*s >= '0' && *s <= '9') s++;
+  if (*s=='\0')
+  {
+    mpz_set_str(i,start,10);
+  }
+  else
+  {
+    char c=*s;
+    *s='\0';
+    mpz_set_str(i,start,10);
+    *s=c;
+  }
+  return s;
+}
+
+/*2
+* extracts the number a from s, returns the rest
+*/
+char * nlRead (char *s, number *a)
+{
+  if (*s<'0' || *s>'9')
+  {
+    *a = nlInit(1);
+    return s;
+  }
+  *a=(number)omAllocBin(rnumber_bin);
+  {
+    (*a)->s = 3;
+#if defined(LDEBUG)
+    (*a)->debug=123456;
+#endif
+    MP_INT *z=&((*a)->z);
+    MP_INT *n=&((*a)->n);
+    mpz_init(z);
+    s = nlEatLong(s, z);
+    if (*s == '/')
+    {
+      mpz_init(n);
+      (*a)->s = 0;
+      s++;
+      s = nlEatLong(s, n);
+      if (mpz_cmp_si(n,(long)0)==0)
+      {
+        WerrorS("Zero Denominator");
+        mpz_clear(n);
+        (*a)->s = 3;
+      }
+      else if (mpz_cmp_si(n,(long)1)==0)
+      {
+        mpz_clear(n);
+        (*a)->s=3;
+      }
+    }
+    if (mpz_cmp_si(z,(long)0)==0)
+    {
+      *a=INT_TO_SR(0);
+    }
+    else
+    if ((*a)->s==3)
+    {
+      int ui=(int)mpz_get_si(&(*a)->z);
+      if ((((ui<<3)>>3)==ui)
+      && (mpz_cmp_si(&(*a)->z,(long)ui)==0))
+      {
+        mpz_clear(&(*a)->z);
+        omFreeBin((ADDRESS)(*a), rnumber_bin);
+        (*a)=INT_TO_SR(ui);
+      }
+    }
+    else
+      nlNormalize(*a);
+  }
+  return s;
+}
+
+/*2
+* write a rational number
+*/
+void nlWrite (number &a)
+{
+  char *s,*z;
+  if (SR_HDL(a) & SR_INT)
+  {
+    StringAppend("%d",SR_TO_INT(a));
+  }
+  else if (a==NULL)
+  {
+    StringAppendS("o");
+  }
+  else
+  {
+    if (a->s==0)
+    {
+      nlNormalize(a);
+      nlWrite(a);
+      return;
+    }
+    int l=mpz_sizeinbase(&a->z,10);
+    if (a->s<2) l=si_max(l,mpz_sizeinbase(&a->n,10));
+    l+=2;
+    s=(char*)omAlloc(l);
+    z=mpz_get_str(s,10,&a->z);
+    StringAppendS(z);
+    if (a->s!=3)
+    {
+      StringAppendS("/");
+      z=mpz_get_str(s,10,&a->n);
+      StringAppendS(z);
+    }
+    omFreeSize((ADDRESS)s,l);
+  }
+}
+
Index: kernel/maps.cc
===================================================================
--- kernel/maps.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/maps.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,508 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: maps.cc,v 1.1.1.1 2003-10-06 12:15:54 Singular Exp $ */
+/*
+* ABSTRACT - the mapping of polynomials to other rings
+*/
+
+#include "mod2.h"
+#include "structs.h"
+#include "febase.h"
+#include "polys.h"
+#include "numbers.h"
+#include "ring.h"
+#include "ideals.h"
+#include "matpol.h"
+#include "omalloc.h"
+#include "kstd1.h"
+#include "longalg.h"
+#include "maps.h"
+#include "prCopy.h"
+
+// This is a very dirty way to "normalize" numbers w.r.t. a
+// MinPoly
+
+/* debug output: Tok2Cmdname in maApplyFetch*/
+//#include "ipshell.h"
+
+#define MAX_MAP_DEG 128
+
+/*2
+* copy a map
+*/
+map maCopy(map theMap)
+{
+  int i;
+  map m=(map)idInit(IDELEMS(theMap),0);
+  for (i=IDELEMS(theMap)-1; i>=0; i--)
+      m->m[i] = pCopy(theMap->m[i]);
+  m->preimage=omStrDup(theMap->preimage);
+  return m;
+}
+
+
+/*2
+* return the image of var(v)^pExp, where var(v) maps to p
+*/
+poly maEvalVariable(poly p, int v,int pExp,matrix s)
+{
+  if (pExp==1)
+    return pCopy(p);
+
+  poly res;
+
+  if((s!=NULL)&&(pExp<MAX_MAP_DEG))
+  {
+    int j=2;
+    poly p0=p;
+    // find starting point
+    if(MATELEM(s,v,1)==NULL)
+    {
+      MATELEM(s,v,1)=pCopy(p/*theMap->m[v-1]*/);
+    }
+    else
+    {
+      while((j<=pExp)&&(MATELEM(s,v,j)!=NULL))
+      {
+        j++;
+      }
+      p0=MATELEM(s,v,j-1);
+    }
+    // multiply
+    for(;j<=pExp;j++)
+    {
+      p0=MATELEM(s,v,j)=ppMult_qq(p0, p);
+      pNormalize(p0);
+    }
+    res=pCopy(p0/*MATELEM(s,v,pExp)*/);
+  }
+  else //if ((p->next!=NULL)&&(p->next->next==NULL))
+  {
+    res=pPower(pCopy(p),pExp);
+  }
+  return res;
+}
+
+static poly maEvalMonom(map theMap, poly p,ring preimage_r,matrix s, nMapFunc nMap)
+{
+    poly q=pNSet(nMap(pGetCoeff(p)));
+
+    int i;
+    for(i=1;i<=preimage_r->N; i++)
+    {
+      int pExp=p_GetExp( p,i,preimage_r);
+      if (pExp != 0)
+      {
+        if (theMap->m[i-1]!=NULL)
+        {
+          poly p1=theMap->m[i-1];
+          poly pp=maEvalVariable(p1,i,pExp,s);
+          q = pMult(q,pp);
+        }
+        else
+        {
+          pDelete(&q);
+          break;
+        }
+      }
+    }
+    int modulComp = p_GetComp( p,preimage_r);
+    if (q!=NULL) pSetCompP(q,modulComp);
+  return q;
+}
+
+poly maEval(map theMap, poly p,ring preimage_r,nMapFunc nMap,matrix s)
+{
+  poly result = NULL;
+  int i;
+
+//  for(i=1; i<=preimage_r->N; i++)
+//  {
+//    pTest(theMap->m[i-1]);
+//  }
+//  while (p!=NULL)
+//  {
+//    poly q=maEvalMonom(theMap,p,preimage_r,s);
+//    result = pAdd(result,q);
+//    pIter(p);
+//  }
+  if (p!=NULL)
+  {
+    int l = pLength(p)-1;
+    poly* monoms;
+    if (l>0)
+    {
+      monoms = (poly*) omAlloc(l*sizeof(poly));
+
+      for (i=0; i<l; i++)
+      {
+        monoms[i]=maEvalMonom(theMap,p,preimage_r,s, nMap);
+        pIter(p);
+      }
+    }
+    result=maEvalMonom(theMap,p,preimage_r,s, nMap);
+    if (l>0)
+    {
+      for(i = l-1; i>=0; i--)
+      {
+        result=pAdd(result, monoms[i]);
+      }
+      omFreeSize((ADDRESS)monoms,l*sizeof(poly));
+    }
+    if (currRing->minpoly!=NULL) result=pMinPolyNormalize(result);
+  }
+  pTest(result);
+  return result;
+}
+
+/*2
+*shifts the variables between minvar and maxvar of p  \in p_ring to the
+*first maxvar-minvar+1 variables in the actual ring
+*be carefull: there is no range check for the variables of p
+*/
+static poly pChangeSizeOfPoly(ring p_ring, poly p,int minvar,int maxvar)
+{
+  int i;
+  poly result = NULL,resultWorkP;
+  number n;
+
+  if (p==NULL) return result;
+  else result = pInit();
+  resultWorkP = result;
+  while (p!=NULL)
+  {
+    for (i=minvar;i<=maxvar;i++)
+      pSetExp(resultWorkP,i-minvar+1,p_GetExp(p,i,p_ring));
+    pSetComp(resultWorkP,p_GetComp(p,p_ring));
+    n=nCopy(pGetCoeff(p));
+    pSetCoeff(resultWorkP,n);
+    pSetm(resultWorkP);
+    pIter(p);
+    if (p!=NULL)
+    {
+      pNext(resultWorkP) = pInit();
+      pIter(resultWorkP);
+    }
+  }
+  return result;
+}
+
+
+/*2
+*returns the preimage of id under theMap,
+*if id is empty or zero the kernel is computed
+*/
+ideal maGetPreimage(ring theImageRing, map theMap, ideal id)
+{
+  int i,j;
+  int ordersize = rBlocks(currRing) + 1;
+  poly p,pp,q;
+  ideal temp1;
+  ideal temp2;
+  int *orders = (int*) omAlloc0(sizeof(int)*(ordersize));
+  int *block0 = (int*) omAlloc0(sizeof(int)*(ordersize));
+  int *block1 = (int*) omAlloc0(sizeof(int)*(ordersize));
+  int **wv = (int **) omAlloc0(ordersize * sizeof(int *));
+
+  int imagepvariables = theImageRing->N;
+  ring sourcering = currRing;
+  int N = pVariables+imagepvariables;
+  char** names = (char**) omAlloc0(N*sizeof(char*));
+
+  memcpy(names, currRing->names, currRing->N*sizeof(char*));
+  memcpy(&(names[currRing->N]), theImageRing->names,
+          (theImageRing->N*sizeof(char*)));
+  sip_sring tmpR;
+
+  //if (theImageRing->OrdSgn == 1)s
+     orders[0] = ringorder_dp;
+  //else orders[0] = ringorder_ls;
+  block1[0] = imagepvariables;
+  block0[0] = 1;
+  /*
+  *if (sourcering->order[blockmax])
+  *{
+  *  if (sourcering->OrdSgn == 1) orders[1] = ringorder_dp;
+  *  else orders[1] = ringorder_ls;
+  *  block1[1] = N;
+  *}
+  *else
+  */
+  for (i=0; i<ordersize - 1; i++)
+  {
+    orders[i+1] = sourcering->order[i];
+    block0[i+1] = sourcering->block0[i]+imagepvariables;
+    block1[i+1] = sourcering->block1[i]+imagepvariables;
+    wv[i+1] = sourcering->wvhdl[i];
+  }
+  tmpR = *currRing;
+  tmpR.N = N;
+  tmpR.order = orders;
+  tmpR.block0 = block0;
+  tmpR.block1 = block1;
+  tmpR.wvhdl = wv;
+  tmpR.names = names;
+  rComplete(&tmpR, 1);
+  rTest(&tmpR);
+
+  // change to new ring
+  rChangeCurrRing(&tmpR);
+  if (id==NULL)
+    j = 0;
+  else
+    j = IDELEMS(id);
+  int j0=j;
+  if (theImageRing->qideal!=NULL) j+=IDELEMS(theImageRing->qideal);
+  temp1 = idInit(sourcering->N+j,1);
+  for (i=0;i<sourcering->N;i++)
+  {
+    q = pISet(-1);
+    pSetExp(q,i+1+imagepvariables,1);
+    pSetm(q);
+    if ((i<IDELEMS(theMap)) && (theMap->m[i]!=NULL))
+    {
+      p = pSort(pChangeSizeOfPoly(theImageRing,theMap->m[i],1,imagepvariables));
+      p=pAdd(p,q);
+    }
+    else
+    {
+      p = q;
+    }
+    temp1->m[i] = p;
+  }
+  idTest(temp1);
+  for (i=sourcering->N;i<sourcering->N+j0;i++)
+  {
+    temp1->m[i] = pSort(pChangeSizeOfPoly(theImageRing,
+                                    id->m[i-sourcering->N],1,imagepvariables));
+  }
+  for (i=sourcering->N+j0;i<sourcering->N+j;i++)
+  {
+    temp1->m[i] = pSort(pChangeSizeOfPoly(theImageRing,
+                                    theImageRing->qideal->m[i-sourcering->N-j0],
+                                    1,imagepvariables));
+  }
+  // we ignore here homogenity - may be changed later:
+  temp2 = kStd(temp1,NULL,isNotHomog,NULL);
+  idDelete(&temp1);
+  for (i=0;i<IDELEMS(temp2);i++)
+  {
+    if (pLowVar(temp2->m[i])<imagepvariables) pDelete(&(temp2->m[i]));
+  }
+
+  // let's get back to the original ring
+  rChangeCurrRing(sourcering);
+  temp1 = idInit(5,1);
+  j = 0;
+  for (i=0;i<IDELEMS(temp2);i++)
+  {
+    p = temp2->m[i];
+    if (p!=NULL)
+    {
+      q = pChangeSizeOfPoly(&tmpR, p,imagepvariables+1,N);
+      if (j>=IDELEMS(temp1))
+      {
+        pEnlargeSet(&(temp1->m),IDELEMS(temp1),5);
+        IDELEMS(temp1)+=5;
+      }
+      temp1->m[j] = q;
+      j++;
+    }
+  }
+  id_Delete(&temp2, &tmpR);
+  idSkipZeroes(temp1);
+  rUnComplete(&tmpR);
+  omFreeSize(orders, sizeof(int)*(ordersize));
+  omFreeSize(block0, sizeof(int)*(ordersize));
+  omFreeSize(block1, sizeof(int)*(ordersize));
+  omFreeSize(wv, sizeof(int*)*(ordersize));
+  omFreeSize(names, (currRing->N)*sizeof(char*));
+  return temp1;
+}
+
+void maFindPerm(char **preim_names, int preim_n, char **preim_par, int preim_p,
+                char **names,       int n,       char **par,       int nop,
+                int * perm, int *par_perm, int ch)
+{
+  int i,j;
+  /* find correspondig vars */
+  for (i=0; i<preim_n; i++)
+  {
+    for(j=0; j<n; j++)
+    {
+      if (strcmp(preim_names[i],names[j])==0)
+      {
+        if (BVERBOSE(V_IMAP))
+          Print("// var %s: nr %d -> nr %d\n",preim_names[i],i+1,j+1);
+        /* var i+1 from preimage ring is var j+1  (index j+1) from image ring */
+        perm[i+1]=j+1;
+        break;
+      }
+    }
+    if ((perm[i+1]==0)&&(par!=NULL)
+        // do not consider par of Fq
+         && (ch < 2))
+    {
+      for(j=0; j<nop; j++)
+      {
+        if (strcmp(preim_names[i],par[j])==0)
+        {
+          if (BVERBOSE(V_IMAP))
+            Print("// var %s: nr %d -> par %d\n",preim_names[i],i+1,j+1);
+          /* var i+1 from preimage ring is par j+1 (index j) from image ring */
+          perm[i+1]=-(j+1);
+        }
+      }
+    }
+  }
+  if (par_perm!=NULL)
+  {
+    for (i=0; i<preim_p; i++)
+    {
+      for(j=0; j<n; j++)
+      {
+        if (strcmp(preim_par[i],names[j])==0)
+        {
+          if (BVERBOSE(V_IMAP))
+            Print("// par %s: par %d -> nr %d\n",preim_par[i],i+1,j+1);
+          /*par i+1 from preimage ring is var j+1  (index j+1) from image ring*/
+          par_perm[i]=j+1;
+          break;
+        }
+      }
+      if ((par!=NULL) && (par_perm[i]==0))
+      {
+        for(j=0; j<nop; j++)
+        {
+          if (strcmp(preim_par[i],par[j])==0)
+          {
+            if (BVERBOSE(V_IMAP))
+              Print("// par %s: nr %d -> par %d\n",preim_par[i],i+1,j+1);
+            /*par i+1 from preimage ring is par j+1 (index j) from image ring */
+            par_perm[i]=-(j+1);
+          }
+        }
+      }
+    }
+  }
+}
+
+/*2
+* embeds poly p from the subring r into the current ring
+*/
+poly maIMap(ring r, poly p)
+{
+  /* the simplest case:*/
+  if(r==currRing) return pCopy(p);
+  nMapFunc nMap=nSetMap(r);
+  int *perm=(int *)omAlloc0((r->N+1)*sizeof(int));
+  //int *par_perm=(int *)omAlloc0(rPar(r)*sizeof(int));
+  maFindPerm(r->names,r->N, r->parameter, r->P,
+             currRing->names,currRing->N,currRing->parameter, currRing->P,
+             perm,NULL, currRing->ch);
+  poly res=pPermPoly(p,perm,r, nMap /*,par_perm,rPar(r)*/);
+  omFreeSize((ADDRESS)perm,(r->N+1)*sizeof(int));
+  //omFreeSize((ADDRESS)par_perm,rPar(r)*sizeof(int));
+  return res;
+}
+
+/*3
+* find the max. degree in one variable, but not larger than MAX_MAP_DEG
+*/
+int maMaxDeg_Ma(ideal a,ring preimage_r)
+{
+  int i,j;
+  int N = preimage_r->N;
+  poly p;
+  int *m=(int *)omAlloc0(N*sizeof(int));
+
+  for (i=MATROWS(a)*MATCOLS(a)-1;i>=0;i--)
+  {
+    p=a->m[i];
+    //pTest(p); // cannot test p because it is from another ring
+    while(p!=NULL)
+    {
+      for(j=N-1;j>=0;j--)
+      {
+        m[j]=si_max(m[j],p_GetExp( p,j+1,preimage_r));
+        if (m[j]>=MAX_MAP_DEG)
+        {
+          i=MAX_MAP_DEG;
+          goto max_deg_fertig_id;
+        }
+      }
+      pIter(p);
+    }
+  }
+  i=m[0];
+  for(j=N-1;j>0;j--)
+  {
+    i=si_max(i,m[j]);
+  }
+max_deg_fertig_id:
+  omFreeSize((ADDRESS)m,N*sizeof(int));
+  return i;
+}
+
+/*3
+* find the max. degree in one variable, but not larger than MAX_MAP_DEG
+*/
+int maMaxDeg_P(poly p,ring preimage_r)
+{
+  int i,j;
+  int N = preimage_r->N;
+  int *m=(int *)omAlloc0(N*sizeof(int));
+
+//  pTest(p);
+  while(p!=NULL)
+  {
+    for(j=N-1;j>=0;j--)
+    {
+      m[j]=si_max(m[j],p_GetExp(p,j+1,preimage_r));
+      if (m[j]>=MAX_MAP_DEG)
+      {
+        i=MAX_MAP_DEG;
+        goto max_deg_fertig_p;
+      }
+    }
+    pIter(p);
+  }
+  i=m[0];
+  for(j=N-1;j>0;j--)
+  {
+    i=si_max(i,m[j]);
+  }
+max_deg_fertig_p:
+  omFreeSize((ADDRESS)m,N*sizeof(int));
+  return i;
+}
+
+// This is a very dirty way to cancel monoms whose number equals the
+// MinPoly
+poly pMinPolyNormalize(poly p)
+{
+  number one = nInit(1);
+  spolyrec rp;
+
+  poly q = &rp;
+
+  while (p != NULL)
+  {
+    // this returns 0, if p == MinPoly
+    number product = nMult(pGetCoeff(p), one);
+    if (product == NULL)
+    {
+      pDeleteLm(&p);
+    }
+    else
+    {
+      pSetCoeff(p, product);
+      pNext(q) = p;
+      q = p;
+      p = pNext(p);
+    }
+  }
+  pNext(q) = NULL;
+  return rp.next;
+}
Index: kernel/maps.h
===================================================================
--- kernel/maps.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/maps.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,31 @@
+#ifndef MAPS_H
+#define MAPS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: maps.h,v 1.1.1.1 2003-10-06 12:15:57 Singular Exp $ */
+/*
+* ABSTRACT - the mapping of polynomials to other rings
+*/
+#include "structs.h"
+
+poly maEval(map theMap, poly p, ring preimage_r, nMapFunc nMap,matrix s=NULL);
+map maCopy(map theMap);
+
+ideal maGetPreimage(ring theImageRing, map theMap,ideal id);
+
+poly maIMap(ring r, poly p);
+
+BOOLEAN maApplyFetch(int what,map theMap,leftv res, leftv w,
+                     ring preimage_r, int *perm,
+                     int *par_perm,int P, nMapFunc nMap);
+void maFindPerm(char **preim_names, int preim_n, char **preim_par, int preim_p,
+                char **names,       int n,       char **par,       int nop,
+                int * perm, int *par_perm, int ch);
+poly pSubstPoly(poly p, int var, poly image);
+ideal  idSubstPoly(ideal id, int n, poly e);
+
+poly pMinPolyNormalize(poly p);
+int maMaxDeg_P(poly p,ring preimage_r);
+int maMaxDeg_Ma(ideal a,ring preimage_r);
+#endif
Index: kernel/matpol.cc
===================================================================
--- kernel/matpol.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/matpol.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1853 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: matpol.cc,v 1.1.1.1 2003-10-06 12:15:53 Singular Exp $ */
+
+/*
+* ABSTRACT:
+*/
+
+#include <stdio.h>
+#include <math.h>
+
+#include "mod2.h"
+#include <mylimits.h>
+#include "structs.h"
+#include "kstd1.h"
+#include "polys.h"
+#include "omalloc.h"
+#include "febase.h"
+#include "numbers.h"
+#include "ideals.h"
+#include "intvec.h"
+#include "ring.h"
+#include "sparsmat.h"
+#include "matpol.h"
+
+
+//omBin ip_smatrix_bin = omGetSpecBin(sizeof(ip_smatrix));
+#define ip_smatrix_bin sip_sideal_bin
+/*0 implementation*/
+
+
+typedef int perm[100];
+static void mpReplace(int j, int n, int &sign, int *perm);
+static int mpNextperm(perm * z, int max);
+static poly mpLeibnitz(matrix a);
+static poly minuscopy (poly p);
+static poly pInsert(poly p1, poly p2);
+static poly mpExdiv ( poly m, poly d, poly vars);
+static poly mpSelect (poly fro, poly what);
+
+static void mpPartClean(matrix, int, int);
+static void mpFinalClean(matrix);
+static int mpPrepareRow (matrix, int, int);
+static int mpPreparePiv (matrix, int, int);
+static int mpPivBar(matrix, int, int);
+static int mpPivRow(matrix, int, int);
+static float mpPolyWeight(poly);
+static void mpSwapRow(matrix, int, int, int);
+static void mpSwapCol(matrix, int, int, int);
+static void mpElimBar(matrix, matrix, poly, int, int);
+
+/*2
+* create a r x c zero-matrix
+*/
+matrix mpNew(int r, int c)
+{
+  if (r<=0) r=1;
+  if ( (((int)(INT_MAX/sizeof(poly))) / r) <= c)
+  {
+    Werror("internal error: creating matrix[%d][%d]",r,c);
+    return NULL;
+  }
+  matrix rc = (matrix)omAllocBin(ip_smatrix_bin);
+  rc->nrows = r;
+  rc->ncols = c;
+  rc->rank = r;
+  if (c != 0)
+  {
+    int s=r*c*sizeof(poly);
+    rc->m = (polyset)omAlloc0(s);
+    //if (rc->m==NULL)
+    //{
+    //  Werror("internal error: creating matrix[%d][%d]",r,c);
+    //  return NULL;
+    //}
+  }
+  return rc;
+}
+
+/*2
+*copies matrix a to b
+*/
+matrix mpCopy (matrix a)
+{
+  idTest((ideal)a);
+  poly t;
+  int i, m=MATROWS(a), n=MATCOLS(a);
+  matrix b = mpNew(m, n);
+
+  for (i=m*n-1; i>=0; i--)
+  {
+    t = a->m[i];
+    pNormalize(t);
+    b->m[i] = pCopy(t);
+  }
+  b->rank=a->rank;
+  return b;
+}
+
+/*2
+* make it a p * unit matrix
+*/
+matrix mpInitP(int r, int c, poly p)
+{
+  matrix rc = mpNew(r,c);
+  int i=si_min(r,c), n = c*(i-1)+i-1, inc = c+1;
+
+  pNormalize(p);
+  while (n>0)
+  {
+    rc->m[n] = pCopy(p);
+    n -= inc;
+  }
+  rc->m[0]=p;
+  return rc;
+}
+
+/*2
+* make it a v * unit matrix
+*/
+matrix mpInitI(int r, int c, int v)
+{
+  return mpInitP(r,c,pISet(v));
+}
+
+/*2
+* c = f*a
+*/
+matrix mpMultI(matrix a, int f)
+{
+  int k, n = a->nrows, m = a->ncols;
+  poly p = pISet(f);
+  matrix c = mpNew(n,m);
+
+  for (k=m*n-1; k>0; k--)
+    c->m[k] = ppMult_qq(a->m[k], p);
+  c->m[0] = pMult(pCopy(a->m[0]), p);
+  return c;
+}
+
+/*2
+* multiply a matrix 'a' by a poly 'p', destroy the args
+*/
+matrix mpMultP(matrix a, poly p)
+{
+  int k, n = a->nrows, m = a->ncols;
+
+  pNormalize(p);
+  for (k=m*n-1; k>0; k--)
+  {  
+    a->m[k] = pMult(a->m[k], pCopy(p));
+  }  
+  a->m[0] = pMult(a->m[0], p);
+  return a;
+}
+
+matrix mpAdd(matrix a, matrix b)
+{
+  int k, n = a->nrows, m = a->ncols;
+  if ((n != b->nrows) || (m != b->ncols))
+  {
+/*
+*    Werror("cannot add %dx%d matrix and %dx%d matrix",
+*      m,n,b->cols(),b->rows());
+*/
+    return NULL;
+  }
+  matrix c = mpNew(n,m);
+  for (k=m*n-1; k>=0; k--)
+    c->m[k] = pAdd(pCopy(a->m[k]), pCopy(b->m[k]));
+  return c;
+}
+
+matrix mpSub(matrix a, matrix b)
+{
+  int k, n = a->nrows, m = a->ncols;
+  if ((n != b->nrows) || (m != b->ncols))
+  {
+/*
+*    Werror("cannot sub %dx%d matrix and %dx%d matrix",
+*      m,n,b->cols(),b->rows());
+*/
+    return NULL;
+  }
+  matrix c = mpNew(n,m);
+  for (k=m*n-1; k>=0; k--)
+    c->m[k] = pSub(pCopy(a->m[k]), pCopy(b->m[k]));
+  return c;
+}
+
+matrix mpMult(matrix a, matrix b)
+{
+  int i, j, k;
+  poly s, t, aik, bkj;
+  int m = MATROWS(a);
+  int p = MATCOLS(a);
+  int q = MATCOLS(b);
+
+  if (p!=MATROWS(b))
+  {
+/*
+*   Werror("cannot multiply %dx%d matrix and %dx%d matrix",
+*     m,p,b->rows(),q);
+*/
+    return NULL;
+  }
+  matrix c = mpNew(m,q);
+
+  for (i=1; i<=m; i++)
+  {
+    for (j=1; j<=q; j++)
+    {
+      t = NULL;
+      for (k=1; k<=p; k++)
+      {
+        s = ppMult_qq(MATELEM(a,i,k), MATELEM(b,k,j));
+        t = pAdd(t,s);
+      }
+      pNormalize(t);
+      MATELEM(c,i,j) = t;
+    }
+  }
+  return c;
+}
+
+matrix mpTransp(matrix a)
+{
+  int    i, j, r = MATROWS(a), c = MATCOLS(a);
+  poly *p;
+  matrix b =  mpNew(c,r);
+
+  p = b->m;
+  for (i=0; i<c; i++)
+  {
+    for (j=0; j<r; j++)
+    {
+      *p++ = pCopy(a->m[j*c+i]);
+    }
+  }
+  return b;
+}
+
+/*2
+*returns the trace of matrix a
+*/
+poly mpTrace ( matrix a)
+{
+  int i;
+  int n = (MATCOLS(a)<MATROWS(a)) ? MATCOLS(a) : MATROWS(a);
+  poly  t = NULL;
+
+  for (i=1; i<=n; i++)
+    t = pAdd(t, pCopy(MATELEM(a,i,i)));
+  return t;
+}
+
+/*2
+*returns the trace of the product of a and b
+*/
+poly TraceOfProd ( matrix a, matrix b, int n)
+{
+  int i, j;
+  poly  p, t = NULL;
+
+  for (i=1; i<=n; i++)
+  {
+    for (j=1; j<=n; j++)
+    {
+      p = ppMult_qq(MATELEM(a,i,j), MATELEM(b,j,i));
+      t = pAdd(t, p);
+    }
+  }
+  return t;
+}
+
+/*
+* C++ classes for Bareiss algorithm
+*/
+class row_col_weight
+{
+  private:
+  int ym, yn;
+  public:
+  float *wrow, *wcol;
+  row_col_weight() : ym(0) {}
+  row_col_weight(int, int);
+  ~row_col_weight();
+};
+
+/*2
+*  a submatrix M of a matrix X[m,n]:
+*    0 <= i < s_m <= a_m
+*    0 <= j < s_n <= a_n
+*    M = ( Xarray[qrow[i],qcol[j]] )
+*    if a_m = a_n and s_m = s_n
+*      det(X) = sign*div^(s_m-1)*det(M)
+*    resticted pivot for elimination
+*      0 <= j < piv_s
+*/
+class mp_permmatrix
+{
+  private:
+  int       a_m, a_n, s_m, s_n, sign, piv_s;
+  int       *qrow, *qcol;
+  poly      *Xarray;
+  void mpInitMat();
+  poly * mpRowAdr(int);
+  poly * mpColAdr(int);
+  void mpRowWeight(float *);
+  void mpColWeight(float *);
+  void mpRowSwap(int, int);
+  void mpColSwap(int, int);
+  public:
+  mp_permmatrix() : a_m(0) {}
+  mp_permmatrix(matrix);
+  mp_permmatrix(mp_permmatrix *);
+  ~mp_permmatrix();
+  int mpGetRow();
+  int mpGetCol();
+  int mpGetRdim();
+  int mpGetCdim();
+  int mpGetSign();
+  void mpSetSearch(int s);
+  void mpSaveArray();
+  poly mpGetElem(int, int);
+  void mpSetElem(poly, int, int);
+  void mpDelElem(int, int);
+  void mpElimBareiss(poly);
+  int mpPivotBareiss(row_col_weight *);
+  int mpPivotRow(row_col_weight *, int);
+  void mpToIntvec(intvec *);
+  void mpRowReorder();
+  void mpColReorder();
+};
+
+#ifndef SIZE_OF_SYSTEM_PAGE
+#define SIZE_OF_SYSTEM_PAGE 4096
+#endif
+/*2
+* entries of a are minors and go to result (only if not in R) 
+*/
+void mpMinorToResult(ideal result, int &elems, matrix a, int r, int c,
+                     ideal R)
+{
+  poly *q1;
+  int e=IDELEMS(result);
+  int i,j;
+
+  if (R != NULL)
+  {
+    for (i=r-1;i>=0;i--)
+    {
+      q1 = &(a->m)[i*a->ncols];
+      for (j=c-1;j>=0;j--)
+      {
+        if (q1[j]!=NULL) q1[j] = kNF(R,currQuotient,q1[j]);
+      }
+    }
+  }
+  for (i=r-1;i>=0;i--)
+  {
+    q1 = &(a->m)[i*a->ncols];
+    for (j=c-1;j>=0;j--)
+    {
+      if (q1[j]!=NULL)
+      {
+        if (elems>=e)
+        {
+          if(e<SIZE_OF_SYSTEM_PAGE)
+          {
+            pEnlargeSet(&(result->m),e,e);
+            e += e;
+          }
+          else
+          {
+            pEnlargeSet(&(result->m),e,SIZE_OF_SYSTEM_PAGE);
+            e += SIZE_OF_SYSTEM_PAGE;
+          }
+          IDELEMS(result) =e;
+        }
+        result->m[elems] = q1[j];
+        q1[j] = NULL;
+        elems++;
+      }
+    }
+  }
+}
+
+/*2
+* produces recursively the ideal of all arxar-minors of a
+*/
+void mpRecMin(int ar,ideal result,int &elems,matrix a,int lr,int lc,
+              poly barDiv, ideal R)
+{
+  int k;
+  int kr=lr-1,kc=lc-1;
+  matrix nextLevel=mpNew(kr,kc);
+
+  loop
+  {
+/*--- look for an optimal row and bring it to last position ------------*/
+    if(mpPrepareRow(a,lr,lc)==0) break;
+/*--- now take all pivotŽs from the last row ------------*/
+    k = lc;
+    loop
+    {
+      if(mpPreparePiv(a,lr,k)==0) break;
+      mpElimBar(a,nextLevel,barDiv,lr,k);
+      k--;
+      if (ar>1)
+      {
+        mpRecMin(ar-1,result,elems,nextLevel,kr,k,a->m[kr*a->ncols+k],R);
+        mpPartClean(nextLevel,kr,k);
+      }
+      else mpMinorToResult(result,elems,nextLevel,kr,k,R);
+      if (ar>k-1) break;
+    }
+    if (ar>=kr) break;
+/*--- now we have to take out the last row...------------*/
+    lr = kr;
+    kr--;
+  }
+  mpFinalClean(nextLevel);
+}
+
+/*2
+*returns the determinant of the matrix m;
+*uses Bareiss algorithm
+*/
+poly mpDetBareiss (matrix a)
+{
+  int s;
+  poly div, res;
+  if (MATROWS(a) != MATCOLS(a))
+  {
+    Werror("det of %d x %d matrix",MATROWS(a),MATCOLS(a));
+    return NULL;
+  }
+  matrix c = mpCopy(a);
+  mp_permmatrix *Bareiss = new mp_permmatrix(c);
+  row_col_weight w(Bareiss->mpGetRdim(), Bareiss->mpGetCdim());
+
+  /* Bareiss */
+  div = NULL;
+  while(Bareiss->mpPivotBareiss(&w))
+  {
+    Bareiss->mpElimBareiss(div);
+    div = Bareiss->mpGetElem(Bareiss->mpGetRdim(), Bareiss->mpGetCdim());
+  }
+  Bareiss->mpRowReorder();
+  Bareiss->mpColReorder();
+  Bareiss->mpSaveArray();
+  s = Bareiss->mpGetSign();
+  delete Bareiss;
+
+  /* result */
+  res = MATELEM(c,1,1);
+  MATELEM(c,1,1) = NULL;
+  idDelete((ideal *)&c);
+  if (s < 0)
+    res = pNeg(res);
+  return res;
+}
+
+/*2
+*returns the determinant of the matrix m;
+*uses Newtons formulea for symmetric functions
+*/
+poly mpDet (matrix m)
+{
+  int i,j,k,n;
+  poly p,q;
+  matrix a, s;
+  matrix ma[100];
+  number c=NULL, d=NULL, ONE=NULL;
+
+  n = MATROWS(m);
+  if (n != MATCOLS(m))
+  {
+    Werror("det of %d x %d matrix",n,MATCOLS(m));
+    return NULL;
+  }
+  k=rChar();
+  if ((k > 0) && (k <= n))
+    return mpLeibnitz(m);
+  ONE = nInit(1);
+  ma[1]=mpCopy(m);
+  k = (n+1) / 2;
+  s = mpNew(1, n);
+  MATELEM(s,1,1) = mpTrace(m);
+  for (i=2; i<=k; i++)
+  {
+    //ma[i] = mpNew(n,n);
+    ma[i]=mpMult(ma[i-1], ma[1]);
+    MATELEM(s,1,i) = mpTrace(ma[i]);
+    pTest(MATELEM(s,1,i));
+  }
+  for (i=k+1; i<=n; i++)
+  {
+    MATELEM(s,1,i) = TraceOfProd(ma[i / 2], ma[(i+1) / 2], n);
+    pTest(MATELEM(s,1,i));
+  }
+  for (i=1; i<=k; i++)
+    idDelete((ideal *)&(ma[i]));
+/* the array s contains the traces of the powers of the matrix m,
+*  these are the power sums of the eigenvalues of m */
+  a = mpNew(1,n);
+  MATELEM(a,1,1) = minuscopy(MATELEM(s,1,1));
+  for (i=2; i<=n; i++)
+  {
+    p = pCopy(MATELEM(s,1,i));
+    for (j=i-1; j>=1; j--)
+    {
+      q = ppMult_qq(MATELEM(s,1,j), MATELEM(a,1,i-j));
+      pTest(q);
+      p = pAdd(p,q);
+    }
+    // c= -1/i
+    d = nInit(-(int)i);
+    c = nDiv(ONE, d);
+    nDelete(&d);
+
+    pMult_nn(p, c);
+    pTest(p);
+    MATELEM(a,1,i) = p;
+    nDelete(&c);
+  }
+/* the array a contains the elementary symmetric functions of the
+*  eigenvalues of m */
+  for (i=1; i<=n-1; i++)
+  {
+    //pDelete(&(MATELEM(a,1,i)));
+    pDelete(&(MATELEM(s,1,i)));
+  }
+  pDelete(&(MATELEM(s,1,n)));
+/* up to a sign, the determinant is the n-th elementary symmetric function */
+  if ((n/2)*2 < n)
+  {
+    d = nInit(-1);
+    pMult_nn(MATELEM(a,1,n), d);
+    nDelete(&d);
+  }
+  nDelete(&ONE);
+  idDelete((ideal *)&s);
+  poly result=MATELEM(a,1,n);
+  MATELEM(a,1,n)=NULL;
+  idDelete((ideal *)&a);
+  return result;
+}
+
+/*2
+* compute all ar-minors of the matrix a
+*/
+matrix mpWedge(matrix a, int ar)
+{
+  int     i,j,k,l;
+  int *rowchoise,*colchoise;
+  BOOLEAN rowch,colch;
+  matrix result;
+  matrix tmp;
+  poly p;
+
+  i = binom(a->nrows,ar);
+  j = binom(a->ncols,ar);
+
+  rowchoise=(int *)omAlloc(ar*sizeof(int));
+  colchoise=(int *)omAlloc(ar*sizeof(int));
+  result =mpNew(i,j);
+  tmp=mpNew(ar,ar);
+  l = 1; /* k,l:the index in result*/
+  idInitChoise(ar,1,a->nrows,&rowch,rowchoise);
+  while (!rowch)
+  {
+    k=1;
+    idInitChoise(ar,1,a->ncols,&colch,colchoise);
+    while (!colch)
+    {
+      for (i=1; i<=ar; i++)
+      {
+        for (j=1; j<=ar; j++)
+        {
+          MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
+        }
+      }
+      p = mpDetBareiss(tmp);
+      if ((k+l) & 1) p=pNeg(p);
+      MATELEM(result,l,k) = p;
+      k++;
+      idGetNextChoise(ar,a->ncols,&colch,colchoise);
+    }
+    idGetNextChoise(ar,a->nrows,&rowch,rowchoise);
+    l++;
+  }
+  /*delete the matrix tmp*/
+  for (i=1; i<=ar; i++)
+  {
+    for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
+  }
+  idDelete((ideal *) &tmp);
+  return (result);
+}
+
+///*2
+//*homogenize all elements of matrix (not the matrix itself)
+//*/
+//matrix mpHomogen(matrix a, int v)
+//{
+//  int i,j;
+//  poly p;
+//
+//  for (i=1;i<=MATROWS(a);i++)
+//  {
+//    for (j=1;j<=MATCOLS(a);j++)
+//    {
+//      p=pHomogen(MATELEM(a,i,j),v);
+//      pDelete(&(MATELEM(a,i,j)));
+//      MATELEM(a,i,j)=p;
+//    }
+//  }
+//  return a;
+//}
+
+/*2
+* corresponds to Maple's coeffs:
+* var has to be the number of a variable
+*/
+matrix mpCoeffs (ideal I, int var)
+{
+  poly h,f;
+  int l, i, c, m=0;
+  matrix co;
+  /* look for maximal power m of x_var in I */
+  for (i=IDELEMS(I)-1; i>=0; i--)
+  {
+    f=I->m[i];
+    while (f!=NULL)
+    {
+      l=pGetExp(f,var);
+      if (l>m) m=l;
+      pIter(f);
+    }
+  }
+  co=mpNew((m+1)*I->rank,IDELEMS(I));
+  /* divide each monomial by a power of x_var,
+  * remember the power in l and the component in c*/
+  for (i=IDELEMS(I)-1; i>=0; i--)
+  {
+    f=I->m[i];
+    while (f!=NULL)
+    {
+      l=pGetExp(f,var);
+      pSetExp(f,var,0);
+      c=si_max((int)pGetComp(f),1);
+      pSetComp(f,0);
+      pSetm(f);
+      /* now add the resulting monomial to co*/
+      h=pNext(f);
+      pNext(f)=NULL;
+      //MATELEM(co,c*(m+1)-l,i+1)
+      //  =pAdd(MATELEM(co,c*(m+1)-l,i+1),f);
+      MATELEM(co,(c-1)*(m+1)+l+1,i+1)
+        =pAdd(MATELEM(co,(c-1)*(m+1)+l+1,i+1),f);
+      /* iterate f*/
+      f=h;
+    }
+  }
+  return co;
+}
+
+/*2
+* given the result c of mpCoeffs(ideal/module i, var)
+* i of rank r
+* build the matrix of the corresponding monomials in m
+*/
+void   mpMonomials(matrix c, int r, int var, matrix m)
+{
+  /* clear contents of m*/
+  int k,l;
+  for (k=MATROWS(m);k>0;k--)
+  {
+    for(l=MATCOLS(m);l>0;l--)
+    {
+      pDelete(&MATELEM(m,k,l));
+    }
+  }
+  omfreeSize((ADDRESS)m->m,MATROWS(m)*MATCOLS(m)*sizeof(poly));
+  /* allocate monoms in the right size r x MATROWS(c)*/
+  m->m=(polyset)omAlloc0(r*MATROWS(c)*sizeof(poly));
+  MATROWS(m)=r;
+  MATCOLS(m)=MATROWS(c);
+  m->rank=r;
+  /* the maximal power p of x_var: MATCOLS(m)=r*(p+1) */
+  int p=MATCOLS(m)/r-1;
+  /* fill in the powers of x_var=h*/
+  poly h=pOne();
+  for(k=r;k>0; k--)
+  {
+    MATELEM(m,k,k*(p+1))=pOne();
+  }
+  for(l=p;l>0; l--)
+  {
+    pSetExp(h,var,l);
+    pSetm(h);
+    for(k=r;k>0; k--)
+    {
+      MATELEM(m,k,k*(p+1)-l)=pCopy(h);
+    }
+  }
+  pDelete(&h);
+}
+
+matrix mpCoeffProc (poly f, poly vars)
+{
+  poly sel, h;
+  int l, i;
+  int pos_of_1 = -1;
+  matrix co;
+
+  if (f==NULL)
+  {
+    co = mpNew(2, 1);
+    MATELEM(co,1,1) = pOne();
+    MATELEM(co,2,1) = NULL;
+    return co;
+  }
+  sel = mpSelect(f, vars);
+  l = pLength(sel);
+  co = mpNew(2, l);
+  if (pOrdSgn==-1)
+  {
+    for (i=l; i>=1; i--)
+    {
+      h = sel;
+      pIter(sel);
+      pNext(h)=NULL;
+      MATELEM(co,1,i) = h;
+      MATELEM(co,2,i) = NULL;
+      if (pIsConstant(h)) pos_of_1 = i;
+    }
+  }
+  else
+  {
+    for (i=1; i<=l; i++)
+    {
+      h = sel;
+      pIter(sel);
+      pNext(h)=NULL;
+      MATELEM(co,1,i) = h;
+      MATELEM(co,2,i) = NULL;
+      if (pIsConstant(h)) pos_of_1 = i;
+    }
+  }
+  while (f!=NULL)
+  {
+    i = 1;
+    loop
+    {
+      if (i!=pos_of_1)
+      {
+        h = mpExdiv(f, MATELEM(co,1,i),vars);
+        if (h!=NULL)
+        {
+          MATELEM(co,2,i) = pAdd(MATELEM(co,2,i), h);
+          break;
+        }
+      }
+      if (i == l)
+      {
+        // check monom 1 last:
+        if (pos_of_1 != -1)
+        {
+          h = mpExdiv(f, MATELEM(co,1,pos_of_1),vars);
+          if (h!=NULL)
+          {
+            MATELEM(co,2,pos_of_1) = pAdd(MATELEM(co,2,pos_of_1), h);
+          }
+        }
+        break;
+      }
+      i ++;
+    }
+    pIter(f);
+  }
+  return co;
+}
+
+/*2
+*exact divisor: let d  == x^i*y^j, m is thought to have only one term;
+*    return m/d iff d divides m, and no x^k*y^l (k>i or l>j) divides m
+* consider all variables in vars
+*/
+static poly mpExdiv ( poly m, poly d, poly vars)
+{
+  int i;
+  poly h = pHead(m);
+  for (i=1; i<=pVariables; i++)
+  {
+    if (pGetExp(vars,i) > 0)
+    {
+      if (pGetExp(d,i) != pGetExp(h,i))
+      {
+        pDelete(&h);
+        return NULL;
+      }
+      pSetExp(h,i,0);
+    }
+  }
+  pSetm(h);
+  return h;
+}
+
+void mpCoef2(poly v, poly mon, matrix *c, matrix *m)
+{
+  polyset s;
+  poly p;
+  int sl,i,j;
+  int l=0;
+  poly sel=mpSelect(v,mon);
+
+  pVec2Polys(sel,&s,&sl);
+  for (i=0; i<sl; i++)
+    l=si_max(l,pLength(s[i]));
+  *c=mpNew(sl,l);
+  *m=mpNew(sl,l);
+  poly h;
+  int isConst;
+  for (j=1; j<=sl;j++)
+  {
+    p=s[j-1];
+    if (pIsConstant(p)) /*p != NULL */
+    {
+      isConst=-1;
+      i=l;
+    }
+    else
+    {
+      isConst=1;
+      i=1;
+    }
+    while(p!=NULL)
+    {
+      h = pHead(p);
+      MATELEM(*m,j,i) = h;
+      i+=isConst;
+      p = p->next;
+    }
+  }
+  while (v!=NULL)
+  {
+    i = 1;
+    j = pGetComp(v);
+    loop
+    {
+      poly mp=MATELEM(*m,j,i);
+      if (mp!=NULL)
+      {
+        h = mpExdiv(v, mp /*MATELEM(*m,j,i)*/, mp);
+        if (h!=NULL)
+        {
+          pSetComp(h,0);
+          MATELEM(*c,j,i) = pAdd(MATELEM(*c,j,i), h);
+          break;
+        }
+      }
+      if (i < l)
+        i++;
+      else
+        break;
+    }
+    v = v->next;
+  }
+}
+
+
+BOOLEAN mpEqual(matrix a, matrix b)
+{
+  if ((MATCOLS(a)!=MATCOLS(b)) || (MATROWS(a)!=MATROWS(b)))
+    return FALSE;
+  int i=MATCOLS(a)*MATROWS(b)-1;
+  while (i>=0)
+  {
+    if (a->m[i]==NULL)
+    {
+      if (b->m[i]!=NULL) return FALSE;
+    }
+    else
+      if (pCmp(a->m[i],b->m[i])!=0) return FALSE;
+    i--;
+  }
+  i=MATCOLS(a)*MATROWS(b)-1;
+  while (i>=0)
+  {
+    if (pSub(pCopy(a->m[i]),pCopy(b->m[i]))!=NULL) return FALSE;
+    i--;
+  }
+  return TRUE;
+}
+
+/* --------------- internal stuff ------------------- */
+
+row_col_weight::row_col_weight(int i, int j)
+{
+  ym = i;
+  yn = j;
+  wrow = (float *)omAlloc(i*sizeof(float));
+  wcol = (float *)omAlloc(j*sizeof(float));
+}
+
+row_col_weight::~row_col_weight()
+{
+  if (ym!=0)
+  {
+    omFreeSize((ADDRESS)wcol, yn*sizeof(float));
+    omFreeSize((ADDRESS)wrow, ym*sizeof(float));
+  }
+}
+
+mp_permmatrix::mp_permmatrix(matrix A) : sign(1)
+{
+  a_m = A->nrows;
+  a_n = A->ncols;
+  this->mpInitMat();
+  Xarray = A->m;
+}
+
+mp_permmatrix::mp_permmatrix(mp_permmatrix *M)
+{
+  poly p, *athis, *aM;
+  int i, j;
+
+  a_m = M->s_m;
+  a_n = M->s_n;
+  sign = M->sign;
+  this->mpInitMat();
+  Xarray = (poly *)omAlloc0(a_m*a_n*sizeof(poly));
+  for (i=a_m-1; i>=0; i--)
+  {
+    athis = this->mpRowAdr(i);
+    aM = M->mpRowAdr(i);
+    for (j=a_n-1; j>=0; j--)
+    {
+      p = aM[M->qcol[j]];
+      if (p)
+      {
+        athis[j] = pCopy(p);
+      }
+    }
+  }
+}
+
+mp_permmatrix::~mp_permmatrix()
+{
+  int k;
+
+  if (a_m != 0)
+  {
+    omFreeSize((ADDRESS)qrow,a_m*sizeof(int));
+    omFreeSize((ADDRESS)qcol,a_n*sizeof(int));
+    if (Xarray != NULL)
+    {
+      for (k=a_m*a_n-1; k>=0; k--)
+        pDelete(&Xarray[k]);
+      omFreeSize((ADDRESS)Xarray,a_m*a_n*sizeof(poly));
+    }
+  }
+}
+
+int mp_permmatrix::mpGetRdim() { return s_m; }
+
+int mp_permmatrix::mpGetCdim() { return s_n; }
+
+int mp_permmatrix::mpGetSign() { return sign; }
+
+void mp_permmatrix::mpSetSearch(int s) { piv_s = s; }
+
+void mp_permmatrix::mpSaveArray() { Xarray = NULL; }
+
+poly mp_permmatrix::mpGetElem(int r, int c)
+{
+  return Xarray[a_n*qrow[r]+qcol[c]];
+}
+
+void mp_permmatrix::mpSetElem(poly p, int r, int c)
+{
+  Xarray[a_n*qrow[r]+qcol[c]] = p;
+}
+
+void mp_permmatrix::mpDelElem(int r, int c)
+{
+  pDelete(&Xarray[a_n*qrow[r]+qcol[c]]);
+}
+
+/*
+* the Bareiss-type elimination with division by div (div != NULL)
+*/
+void mp_permmatrix::mpElimBareiss(poly div)
+{
+  poly piv, elim, q1, q2, *ap, *a;
+  int i, j, jj;
+
+  ap = this->mpRowAdr(s_m);
+  piv = ap[qcol[s_n]];
+  for(i=s_m-1; i>=0; i--)
+  {
+    a = this->mpRowAdr(i);
+    elim = a[qcol[s_n]];
+    if (elim != NULL)
+    {
+      elim = pNeg(elim);
+      for (j=s_n-1; j>=0; j--)
+      {
+        q2 = NULL;
+        jj = qcol[j];
+        if (ap[jj] != NULL)
+        {
+          q2 = SM_MULT(ap[jj], elim, div);
+          if (a[jj] != NULL)
+          {
+            q1 = SM_MULT(a[jj], piv, div);
+            pDelete(&a[jj]);
+            q2 = pAdd(q2, q1);
+          }
+        }
+        else if (a[jj] != NULL)
+        {
+          q2 = SM_MULT(a[jj], piv, div);
+        }
+        if ((q2!=NULL) && div)
+          SM_DIV(q2, div);
+        a[jj] = q2;
+      }
+      pDelete(&a[qcol[s_n]]);
+    }
+    else
+    {
+      for (j=s_n-1; j>=0; j--)
+      {
+        jj = qcol[j];
+        if (a[jj] != NULL)
+        {
+          q2 = SM_MULT(a[jj], piv, div);
+          pDelete(&a[jj]);
+          if (div)
+            SM_DIV(q2, div);
+          a[jj] = q2;
+        }
+      }
+    }
+  }
+}
+
+/*2
+* pivot strategy for Bareiss algorithm
+*/
+int mp_permmatrix::mpPivotBareiss(row_col_weight *C)
+{
+  poly p, *a;
+  int i, j, iopt, jopt;
+  float sum, f1, f2, fo, r, ro, lp;
+  float *dr = C->wrow, *dc = C->wcol;
+
+  fo = 1.0e20;
+  ro = 0.0;
+  iopt = jopt = -1;
+
+  s_n--;
+  s_m--;
+  if (s_m == 0)
+    return 0;
+  if (s_n == 0)
+  {
+    for(i=s_m; i>=0; i--)
+    {
+      p = this->mpRowAdr(i)[qcol[0]];
+      if (p)
+      {
+        f1 = mpPolyWeight(p);
+        if (f1 < fo)
+        {
+          fo = f1;
+          if (iopt >= 0)
+            pDelete(&(this->mpRowAdr(iopt)[qcol[0]]));
+          iopt = i;
+        }
+        else
+          pDelete(&(this->mpRowAdr(i)[qcol[0]]));
+      }
+    }
+    if (iopt >= 0)
+      mpReplace(iopt, s_m, sign, qrow);
+    return 0;
+  }
+  this->mpRowWeight(dr);
+  this->mpColWeight(dc);
+  sum = 0.0;
+  for(i=s_m; i>=0; i--)
+    sum += dr[i];
+  for(i=s_m; i>=0; i--)
+  {
+    r = dr[i];
+    a = this->mpRowAdr(i);
+    for(j=s_n; j>=0; j--)
+    {
+      p = a[qcol[j]];
+      if (p)
+      {
+        lp = mpPolyWeight(p);
+        ro = r - lp;
+        f1 = ro * (dc[j]-lp);
+        if (f1 != 0.0)
+        {
+          f2 = lp * (sum - ro - dc[j]);
+          f2 += f1;
+        }
+        else
+          f2 = lp-r-dc[j];
+        if (f2 < fo)
+        {
+          fo = f2;
+          iopt = i;
+          jopt = j;
+        }
+      }
+    }
+  }
+  if (iopt < 0)
+    return 0;
+  mpReplace(iopt, s_m, sign, qrow);
+  mpReplace(jopt, s_n, sign, qcol);
+  return 1;
+}
+
+/*2
+* pivot strategy for Bareiss algorithm with defined row
+*/
+int mp_permmatrix::mpPivotRow(row_col_weight *C, int row)
+{
+  poly p, *a;
+  int j, iopt, jopt;
+  float sum, f1, f2, fo, r, ro, lp;
+  float *dr = C->wrow, *dc = C->wcol;
+
+  fo = 1.0e20;
+  ro = 0.0;
+  iopt = jopt = -1;
+
+  s_n--;
+  s_m--;
+  if (s_m == 0)
+    return 0;
+  if (s_n == 0)
+  {
+    p = this->mpRowAdr(row)[qcol[0]];
+    if (p)
+    {
+      f1 = mpPolyWeight(p);
+      if (f1 < fo)
+      {
+        fo = f1;
+        if (iopt >= 0)
+        pDelete(&(this->mpRowAdr(iopt)[qcol[0]]));
+        iopt = row;
+      }
+      else
+        pDelete(&(this->mpRowAdr(row)[qcol[0]]));
+    }
+    if (iopt >= 0)
+      mpReplace(iopt, s_m, sign, qrow);
+    return 0;
+  }
+  this->mpRowWeight(dr);
+  this->mpColWeight(dc);
+  sum = 0.0;
+  for(j=s_m; j>=0; j--)
+    sum += dr[j];
+  r = dr[row];
+  a = this->mpRowAdr(row);
+  for(j=s_n; j>=0; j--)
+  {
+    p = a[qcol[j]];
+    if (p)
+    {
+      lp = mpPolyWeight(p);
+      ro = r - lp;
+      f1 = ro * (dc[j]-lp);
+      if (f1 != 0.0)
+      {
+        f2 = lp * (sum - ro - dc[j]);
+        f2 += f1;
+      }
+      else
+        f2 = lp-r-dc[j];
+      if (f2 < fo)
+      {
+        fo = f2;
+        iopt = row;
+        jopt = j;
+      }
+    }
+  }
+  if (iopt < 0)
+    return 0;
+  mpReplace(iopt, s_m, sign, qrow);
+  mpReplace(jopt, s_n, sign, qcol);
+  return 1;
+}
+
+void mp_permmatrix::mpToIntvec(intvec *v)
+{
+  int i;
+
+  for (i=v->rows()-1; i>=0; i--)
+    (*v)[i] = qcol[i]+1;
+}
+
+void mp_permmatrix::mpRowReorder()
+{
+  int k, i, i1, i2;
+
+  if (a_m > a_n)
+    k = a_m - a_n;
+  else
+    k = 0;
+  for (i=a_m-1; i>=k; i--)
+  {
+    i1 = qrow[i];
+    if (i1 != i)
+    {
+      this->mpRowSwap(i1, i);
+      i2 = 0;
+      while (qrow[i2] != i) i2++;
+      qrow[i2] = i1;
+    }
+  }
+}
+
+void mp_permmatrix::mpColReorder()
+{
+  int k, j, j1, j2;
+
+  if (a_n > a_m)
+    k = a_n - a_m;
+  else
+    k = 0;
+  for (j=a_n-1; j>=k; j--)
+  {
+    j1 = qcol[j];
+    if (j1 != j)
+    {
+      this->mpColSwap(j1, j);
+      j2 = 0;
+      while (qcol[j2] != j) j2++;
+      qcol[j2] = j1;
+    }
+  }
+}
+
+// private
+void mp_permmatrix::mpInitMat()
+{
+  int k;
+
+  s_m = a_m;
+  s_n = a_n;
+  piv_s = 0;
+  qrow = (int *)omAlloc(a_m*sizeof(int));
+  qcol = (int *)omAlloc(a_n*sizeof(int));
+  for (k=a_m-1; k>=0; k--) qrow[k] = k;
+  for (k=a_n-1; k>=0; k--) qcol[k] = k;
+}
+
+poly * mp_permmatrix::mpRowAdr(int r)
+{
+  return &(Xarray[a_n*qrow[r]]);
+}
+
+poly * mp_permmatrix::mpColAdr(int c)
+{
+  return &(Xarray[qcol[c]]);
+}
+
+void mp_permmatrix::mpRowWeight(float *wrow)
+{
+  poly p, *a;
+  int i, j;
+  float count;
+
+  for (i=s_m; i>=0; i--)
+  {
+    a = this->mpRowAdr(i);
+    count = 0.0;
+    for(j=s_n; j>=0; j--)
+    {
+      p = a[qcol[j]];
+      if (p)
+        count += mpPolyWeight(p);
+    }
+    wrow[i] = count;
+  }
+}
+
+void mp_permmatrix::mpColWeight(float *wcol)
+{
+  poly p, *a;
+  int i, j;
+  float count;
+
+  for (j=s_n; j>=0; j--)
+  {
+    a = this->mpColAdr(j);
+    count = 0.0;
+    for(i=s_m; i>=0; i--)
+    {
+      p = a[a_n*qrow[i]];
+      if (p)
+        count += mpPolyWeight(p);
+    }
+    wcol[j] = count;
+  }
+}
+
+void mp_permmatrix::mpRowSwap(int i1, int i2)
+{
+   poly p, *a1, *a2;
+   int j;
+
+   a1 = &(Xarray[a_n*i1]);
+   a2 = &(Xarray[a_n*i2]);
+   for (j=a_n-1; j>= 0; j--)
+   {
+     p = a1[j];
+     a1[j] = a2[j];
+     a2[j] = p;
+   }
+}
+
+void mp_permmatrix::mpColSwap(int j1, int j2)
+{
+   poly p, *a1, *a2;
+   int i, k = a_n*a_m;
+
+   a1 = &(Xarray[j1]);
+   a2 = &(Xarray[j2]);
+   for (i=0; i< k; i+=a_n)
+   {
+     p = a1[i];
+     a1[i] = a2[i];
+     a2[i] = p;
+   }
+}
+
+int mp_permmatrix::mpGetRow()
+{
+  return qrow[s_m];
+}
+
+int mp_permmatrix::mpGetCol()
+{
+  return qcol[s_n];
+}
+
+/*
+* perform replacement for pivot strategy in Bareiss algorithm
+* change sign of determinant
+*/
+static void mpReplace(int j, int n, int &sign, int *perm)
+{
+  int k;
+
+  if (j != n)
+  {
+    k = perm[n];
+    perm[n] = perm[j];
+    perm[j] = k;
+    sign = -sign;
+  }
+}
+
+static int mpNextperm(perm * z, int max)
+{
+  int s, i, k, t;
+  s = max;
+  do
+  {
+    s--;
+  }
+  while ((s > 0) && ((*z)[s] >= (*z)[s+1]));
+  if (s==0)
+    return 0;
+  do
+  {
+    (*z)[s]++;
+    k = 0;
+    do
+    {
+      k++;
+    }
+    while (((*z)[k] != (*z)[s]) && (k!=s));
+  }
+  while (k < s);
+  for (i=s+1; i <= max; i++)
+  {
+    (*z)[i]=0;
+    do
+    {
+      (*z)[i]++;
+      k=0;
+      do
+      {
+        k++;
+      }
+      while (((*z)[k] != (*z)[i]) && (k != i));
+    }
+    while (k < i);
+  }
+  s = max+1;
+  do
+  {
+    s--;
+  }
+  while ((s > 0) && ((*z)[s] > (*z)[s+1]));
+  t = 1;
+  for (i=1; i<max; i++)
+    for (k=i+1; k<=max; k++)
+      if ((*z)[k] < (*z)[i])
+        t = -t;
+  (*z)[0] = t;
+  return s;
+}
+
+static poly mpLeibnitz(matrix a)
+{
+  int i, e, n;
+  poly p, d;
+  perm z;
+
+  n = MATROWS(a);
+  memset(&z,0,(n+2)*sizeof(int));
+  p = pOne();
+  for (i=1; i <= n; i++)
+    p = pMult(p, pCopy(MATELEM(a, i, i)));
+  d = p;
+  for (i=1; i<= n; i++)
+    z[i] = i;
+  z[0]=1;
+  e = 1;
+  if (n!=1)
+  {
+    while (e)
+    {
+      e = mpNextperm((perm *)&z, n);
+      p = pOne();
+      for (i = 1; i <= n; i++)
+        p = pMult(p, pCopy(MATELEM(a, i, z[i])));
+      if (z[0] > 0)
+        d = pAdd(d, p);
+      else
+        d = pSub(d, p);
+    }
+  }
+  return d;
+}
+
+static poly minuscopy (poly p)
+{
+  poly w;
+  number  e;
+  e = nInit(-1);
+  w = pCopy(p);
+  pMult_nn(w, e);
+  nDelete(&e);
+  return w;
+}
+
+/*2
+* insert a monomial into a list, avoid duplicates
+* arguments are destroyed
+*/
+static poly pInsert(poly p1, poly p2)
+{
+  poly a1, p, a2, a;
+  int c;
+
+  if (p1==NULL) return p2;
+  if (p2==NULL) return p1;
+  a1 = p1;
+  a2 = p2;
+  a = p  = pOne();
+  loop
+  {
+    c = pCmp(a1, a2);
+    if (c == 1)
+    {
+      a = pNext(a) = a1;
+      pIter(a1);
+      if (a1==NULL)
+      {
+        pNext(a) = a2;
+        break;
+      }
+    }
+    else if (c == -1)
+    {
+      a = pNext(a) = a2;
+      pIter(a2);
+      if (a2==NULL)
+      {
+        pNext(a) = a1;
+        break;
+      }
+    }
+    else
+    {
+      pDeleteLm(&a2);
+      a = pNext(a) = a1;
+      pIter(a1);
+      if (a1==NULL)
+      {
+        pNext(a) = a2;
+        break;
+      }
+      else if (a2==NULL)
+      {
+        pNext(a) = a1;
+        break;
+      }
+    }
+  }
+  pDeleteLm(&p);
+  return p;
+}
+
+/*2
+*if what == xy the result is the list of all different power products
+*    x^i*y^j (i, j >= 0) that appear in fro
+*/
+static poly mpSelect (poly fro, poly what)
+{
+  int i;
+  poly h, res;
+  res = NULL;
+  while (fro!=NULL)
+  {
+    h = pOne();
+    for (i=1; i<=pVariables; i++)
+      pSetExp(h,i, pGetExp(fro,i) * pGetExp(what, i));
+    pSetComp(h, pGetComp(fro));
+    pSetm(h);
+    res = pInsert(h, res);
+    fro = fro->next;
+  }
+  return res;
+}
+
+/*
+*static void ppp(matrix a)
+*{
+*  int j,i,r=a->nrows,c=a->ncols;
+*  for(j=1;j<=r;j++)
+*  {
+*    for(i=1;i<=c;i++)
+*    {
+*      if(MATELEM(a,j,i)!=NULL) Print("X");
+*      else Print("0");
+*    }
+*    Print("\n");
+*  }
+*}
+*/
+
+static void mpPartClean(matrix a, int lr, int lc)
+{
+  poly *q1;
+  int i,j;
+
+  for (i=lr-1;i>=0;i--)
+  {
+    q1 = &(a->m)[i*a->ncols];
+    for (j=lc-1;j>=0;j--) if(q1[j]) pDelete(&q1[j]);
+  }
+}
+
+static void mpFinalClean(matrix a)
+{
+  omFreeSize((ADDRESS)a->m,a->nrows*a->ncols*sizeof(poly));
+  omFreeBin((ADDRESS)a, ip_smatrix_bin);
+}
+
+/*2
+*  prepare one step of 'Bareiss' algorithm
+*  for application in minor
+*/
+static int mpPrepareRow (matrix a, int lr, int lc)
+{
+  int r;
+
+  r = mpPivBar(a,lr,lc);
+  if(r==0) return 0;
+  if(r<lr) mpSwapRow(a, r, lr, lc);
+  return 1;
+}
+
+/*2
+*  prepare one step of 'Bareiss' algorithm
+*  for application in minor
+*/
+static int mpPreparePiv (matrix a, int lr, int lc)
+{
+  int c;
+
+  c = mpPivRow(a, lr, lc);
+  if(c==0) return 0;
+  if(c<lc) mpSwapCol(a, c, lr, lc);
+  return 1;
+}
+
+/*
+* find best row
+*/
+static int mpPivBar(matrix a, int lr, int lc)
+{
+  float f1, f2;
+  poly *q1;
+  int i,j,io;
+
+  io = -1;
+  f1 = 1.0e30;
+  for (i=lr-1;i>=0;i--)
+  {
+    q1 = &(a->m)[i*a->ncols];
+    f2 = 0.0;
+    for (j=lc-1;j>=0;j--)
+    {
+      if (q1[j]!=NULL)
+        f2 += mpPolyWeight(q1[j]);
+    }
+    if ((f2!=0.0) && (f2<f1))
+    {
+      f1 = f2;
+      io = i;
+    }
+  }
+  if (io<0) return 0;
+  else return io+1;
+}
+
+/*
+* find pivot in the last row
+*/
+static int mpPivRow(matrix a, int lr, int lc)
+{
+  float f1, f2;
+  poly *q1;
+  int j,jo;
+
+  jo = -1;
+  f1 = 1.0e30;
+  q1 = &(a->m)[(lr-1)*a->ncols];
+  for (j=lc-1;j>=0;j--)
+  {
+    if (q1[j]!=NULL)
+    {
+      f2 = mpPolyWeight(q1[j]);
+      if (f2<f1)
+      {
+        f1 = f2;
+        jo = j;
+      }
+    }
+  }
+  if (jo<0) return 0;
+  else return jo+1;
+}
+
+/*
+* weigth of a polynomial, for pivot strategy
+*/
+static float mpPolyWeight(poly p)
+{
+  int i;
+  float res;
+
+  if (pNext(p) == NULL)
+  {
+    res = (float)nSize(pGetCoeff(p));
+    for (i=pVariables;i>0;i--)
+    {
+      if(pGetExp(p,i)!=0)
+      {
+        res += 2.0;
+        break;
+      }
+    }
+  }
+  else
+  {
+    res = 0.0;
+    do
+    {
+      res += (float)nSize(pGetCoeff(p))+2.0;
+      pIter(p);
+    }
+    while (p);
+  }
+  return res;
+}
+
+static void mpSwapRow(matrix a, int pos, int lr, int lc)
+{
+  poly sw;
+  int j;
+  polyset a2 = a->m, a1 = &a2[a->ncols*(pos-1)];
+
+  a2 = &a2[a->ncols*(lr-1)];
+  for (j=lc-1; j>=0; j--)
+  {
+    sw = a1[j];
+    a1[j] = a2[j];
+    a2[j] = sw;
+  }
+}
+
+static void mpSwapCol(matrix a, int pos, int lr, int lc)
+{
+  poly sw;
+  int j;
+  polyset a2 = a->m, a1 = &a2[pos-1];
+
+  a2 = &a2[lc-1];
+  for (j=a->ncols*(lr-1); j>=0; j-=a->ncols)
+  {
+    sw = a1[j];
+    a1[j] = a2[j];
+    a2[j] = sw;
+  }
+}
+
+static void mpElimBar(matrix a0, matrix re, poly div, int lr, int lc)
+{
+  int r=lr-1, c=lc-1;
+  poly *b = a0->m, *x = re->m;
+  poly piv, elim, q1, q2, *ap, *a, *q;
+  int i, j;
+
+  ap = &b[r*a0->ncols];
+  piv = ap[c];
+  for(j=c-1; j>=0; j--)
+    if (ap[j] != NULL) ap[j] = pNeg(ap[j]);
+  for(i=r-1; i>=0; i--)
+  {
+    a = &b[i*a0->ncols];
+    q = &x[i*re->ncols];
+    if (a[c] != NULL)
+    {
+      elim = a[c];
+      for (j=c-1; j>=0; j--)
+      {
+        q1 = NULL;
+        if (a[j] != NULL)
+        {
+          q1 = SM_MULT(a[j], piv, div);
+          if (ap[j] != NULL)
+          {
+            q2 = SM_MULT(ap[j], elim, div);
+            q1 = pAdd(q1,q2);
+          }
+        }
+        else if (ap[j] != NULL)
+          q1 = SM_MULT(ap[j], elim, div);
+        if (q1 != NULL)
+        {
+          if (div)
+            SM_DIV(q1, div);
+          q[j] = q1;
+        }
+      }
+    }
+    else
+    {
+      for (j=c-1; j>=0; j--)
+      {
+        if (a[j] != NULL)
+        {
+          q1 = SM_MULT(a[j], piv, div);
+          if (div)
+            SM_DIV(q1, div);
+          q[j] = q1;
+        }
+      }
+    }
+  }
+}
+
+BOOLEAN mpIsDiagUnit(matrix U)
+{
+  if(MATROWS(U)!=MATCOLS(U))
+    return FALSE;
+  for(int i=MATCOLS(U);i>=1;i--)
+  {
+    for(int j=MATCOLS(U); j>=1; j--)
+    {
+      if (i==j)
+      {
+        if (!pIsUnit(MATELEM(U,i,i))) return FALSE;
+      }
+      else if (MATELEM(U,i,j)!=NULL) return FALSE;
+    }  
+  }
+  return TRUE;
+}
+
+void iiWriteMatrix(matrix im, const char *n, int dim,int spaces)
+{
+  int i,ii = MATROWS(im)-1;
+  int j,jj = MATCOLS(im)-1;
+  poly *pp = im->m;
+
+  for (i=0; i<=ii; i++)
+  {
+    for (j=0; j<=jj; j++)
+    {
+      if (spaces>0)
+        Print("%-*.*s",spaces,spaces," ");
+      if (dim == 2) Print("%s[%u,%u]=",n,i+1,j+1);
+      else if (dim == 1) Print("%s[%u]=",n,j+1);
+      else if (dim == 0) Print("%s=",n);
+      if ((i<ii)||(j<jj)) pWrite(*pp++);
+      else                pWrite0(*pp);
+    }
+  }
+}
+
+char * iiStringMatrix(matrix im, int dim,char ch)
+{
+  int i,ii = MATROWS(im);
+  int j,jj = MATCOLS(im);
+  poly *pp = im->m;
+  char *s=StringSetS("");
+
+  for (i=0; i<ii; i++)
+  {
+    for (j=0; j<jj; j++)
+    {
+      pString0(*pp++);
+      s=StringAppend("%c",ch);
+      if (dim > 1) s = StringAppendS("\n");
+    }
+  }
+  s[strlen(s)- (dim > 1 ? 2 : 1)]='\0';
+  return s;
+}
+
Index: kernel/matpol.h
===================================================================
--- kernel/matpol.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/matpol.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,76 @@
+#ifndef MATPOL_H
+#define MATPOL_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: matpol.h,v 1.1.1.1 2003-10-06 12:15:57 Singular Exp $ */
+/*
+* ABSTRACT
+*/
+#include "structs.h"
+
+// THIS IS REALLY DIRTY: ip_smatrix HAS TO BE IDENTICAL TO ip_sideal
+// SO, DON'T CHANGE THE DECLARATION OF ip_smatrix
+class ip_smatrix
+{
+  public:
+
+  poly *m;
+  long rank;
+  int nrows;
+  int ncols;
+
+  inline int& rows() { return nrows; }
+  inline int& cols() { return ncols; }
+
+  #define MATROWS(i) ((i)->nrows)
+  #define MATCOLS(i) ((i)->ncols)
+  #define MATELEM(mat,i,j) ((mat)->m)[MATCOLS((mat)) * ((i)-1) + (j)-1]
+};
+
+matrix mpNew(int r, int c);
+matrix mpCopy (matrix a);
+matrix mpInitP(int r, int c, poly p);
+matrix mpInitI(int r, int c, int v);
+matrix mpMultI(matrix a, int f);
+matrix mpMultP(matrix a, poly p);
+matrix mpAdd(matrix a, matrix b);
+matrix mpSub(matrix a, matrix b);
+matrix mpMult(matrix a, matrix b);
+matrix mpTransp(matrix a);
+BOOLEAN mpEqual(matrix a, matrix b);
+poly mpTrace ( matrix a);
+poly TraceOfProd ( matrix a, matrix b, int n);
+
+poly mpDet (matrix m);
+matrix mpWedge(matrix a, int ar);
+BOOLEAN mpJacobi(leftv res,leftv a);
+BOOLEAN mpKoszul(leftv res,leftv b/*in*/, leftv c/*ip*/, leftv id=NULL);
+poly mpDetBareiss (matrix a);
+
+//matrix mpHomogen(matrix a, int v);
+
+void   mpMonomials(matrix c, int r, int var, matrix m);
+matrix mpCoeffs(ideal I, int var);
+/* corresponds to Maple's coeffs:
+*var has to be the number of a variable
+*/
+
+matrix mpCoeffProc (poly f, poly vars);
+/* corresponds to Macauley's coef:
+the exponent vector of vars has to contain the variables, eg 'xy';
+then the poly f is searched for monomials in x and y, these monimials
+are written to the first row of the matrix co.
+the second row of co contains the respective factors in f.
+Thus f = sum co[1,i]*co[2,i], i = 1..cols, rows equals 2. */
+void mpCoef2(poly v, poly vars, matrix *c, matrix *m);
+/* for minors with Bareiss */
+void mpRecMin(int, ideal, int &, matrix, int, int, poly, ideal);
+void mpMinorToResult(ideal, int &, matrix, int, int, ideal);
+
+BOOLEAN mpIsDiagUnit(matrix U);
+void iiWriteMatrix(matrix im, const char *n, int dim,int spaces=0);
+char * iiStringMatrix(matrix im, int dim,char ch=',');
+
+extern omBin ip_smatrix_bin;
+#endif
Index: kernel/misc.cc
===================================================================
--- kernel/misc.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/misc.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,191 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT:
+*/
+
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "mod2.h"
+#include <mylimits.h>
+#include "omalloc.h"
+#include "structs.h"
+#include "febase.h"
+//#include "cntrlc.h"
+#include "kstd1.h"
+#include "timer.h"
+#include "intvec.h"
+#include "ring.h"
+#include "omSingularConfig.h"
+#include "p_Procs.h"
+#include "version.h"
+
+#include "static.h"
+#ifdef HAVE_STATIC
+#undef HAVE_DYN_RL
+#endif
+
+#define SI_DONT_HAVE_GLOBAL_VARS
+
+//#ifdef HAVE_LIBPARSER
+//#  include "libparse.h"
+//#endif /* HAVE_LIBPARSER */
+
+#ifdef HAVE_FACTORY
+#include <factory.h>
+#endif
+
+/* version strings */
+#ifdef HAVE_LIBFAC_P
+  extern const char * libfac_version;
+  extern const char * libfac_date;
+#endif
+extern "C" {
+#include <gmp.h>
+}
+#ifdef HAVE_MPSR
+#include <MP_Config.h>
+#endif
+
+/* init bins from structs.h */
+
+omBin MP_INT_bin = omGetSpecBin(sizeof(MP_INT));
+omBin char_ptr_bin = omGetSpecBin(sizeof(char_ptr));
+omBin ideal_bin = omGetSpecBin(sizeof(ideal));
+omBin int_bin = omGetSpecBin(sizeof(int));
+omBin poly_bin = omGetSpecBin(sizeof(poly));
+omBin void_ptr_bin = omGetSpecBin(sizeof(void_ptr));
+omBin indlist_bin = omGetSpecBin(sizeof(indlist));
+omBin naIdeal_bin = omGetSpecBin(sizeof(naIdeal));
+omBin snaIdeal_bin = omGetSpecBin(sizeof(snaIdeal));
+omBin sm_prec_bin = omGetSpecBin(sizeof(sm_prec));
+omBin smprec_bin = omGetSpecBin(sizeof(smprec));
+omBin sip_sideal_bin = omGetSpecBin(sizeof(sip_sideal));
+omBin sip_smap_bin = omGetSpecBin(sizeof(sip_smap));
+omBin sip_sring_bin = omGetSpecBin(sizeof(sip_sring));
+omBin ip_sideal_bin = omGetSpecBin(sizeof(ip_sideal));
+omBin ip_smap_bin = omGetSpecBin(sizeof(ip_smap));
+omBin ip_sring_bin = omGetSpecBin(sizeof(ip_sring));
+
+/*0 implementation*/
+
+/*2
+* the global exit routine of Singular
+*/
+extern "C" {
+void m2_end(short i)
+{
+  fe_reset_input_mode();
+  #ifdef PAGE_TEST
+  mmEndStat();
+  #endif
+  #ifdef HAVE_TCL
+  if (tclmode)
+  {
+    PrintTCL('Q',0,NULL);
+  }
+  #endif
+  fe_reset_input_mode();
+  if (i<=0)
+  {
+    #ifdef HAVE_TCL
+    if (!tclmode)
+    #endif
+      if (BVERBOSE(0))
+      {
+        if (i==0)
+          printf("Auf Wiedersehen.\n");
+        else
+          printf("\n$Bye.\n");
+      }
+    #ifdef sun
+      #ifndef __svr4__
+        _cleanup();
+        _exit(0);
+      #endif
+    #endif
+    exit(0);
+  }
+  else
+  {
+    #ifdef HAVE_TCL
+    if (!tclmode)
+    #endif
+      printf("\nhalt %d\n",i);
+  }
+  exit(i);
+}
+}
+
+/*2
+* the renice routine for very large jobs
+* works only on unix machines,
+* testet on : linux, HP 9.0
+*
+*#ifndef MSDOS
+*#ifndef macintosh
+*#include <sys/times.h>
+*#include <sys/resource.h>
+*extern "C" int setpriority(int,int,int);
+*void very_nice()
+*{
+*#ifndef NO_SETPRIORITY
+*  setpriority(PRIO_PROCESS,0,19);
+*#endif
+*  sleep(10);
+*}
+*#else
+*void very_nice(){}
+*#endif
+*#else
+*void very_nice(){}
+*#endif
+*/
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#ifdef buildin_rand
+/*
+ *
+ *  A prime modulus multiplicative linear congruential
+ *  generator (PMMLCG), or "Lehmer generator".
+ *  Implementation directly derived from the article:
+ *
+ *        S. K. Park and K. W. Miller
+ *        Random Number Generators: Good Ones are Hard to Find
+ *        CACM vol 31, #10. Oct. 1988. pp 1192-1201.
+ *
+ *  Using the following multiplier and modulus, we obtain a
+ *  generator which:
+ *
+ *        1)  Has a full period: 1 to 2^31 - 2.
+ *        2)  Is testably "random" (see the article).
+ *        3)  Has a known implementation by E. L. Schrage.
+ */
+
+
+#define  A        16807L        /*  A "good" multiplier          */
+#define  M   2147483647L        /*  Modulus: 2^31 - 1          */
+#define  Q       127773L        /*  M / A                  */
+#define  R         2836L        /*  M % A                  */
+
+
+int siSeed = 1L;
+
+
+int siRand()
+{
+  siSeed = A * (siSeed % Q) - R * (siSeed / Q);
+
+  if ( siSeed < 0 )
+    siSeed += M;
+
+  return( siSeed );
+}
+#endif
+
Index: kernel/mkinstalldirs
===================================================================
--- kernel/mkinstalldirs	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/mkinstalldirs	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,32 @@
+#!/bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Last modified: 1994-03-25
+# Public domain
+
+errstatus=0
+
+for file in ${1+"$@"} ; do 
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d in ${1+"$@"} ; do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+        echo "mkdir $pathcomp" 1>&2
+        mkdir "$pathcomp" || errstatus=$?
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
Index: kernel/mmalloc.cc
===================================================================
--- kernel/mmalloc.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/mmalloc.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,40 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: mmalloc.cc,v 1.1.1.1 2003-10-06 12:15:57 Singular Exp $ */
+/*
+* ABSTRACT: standard version of C++-memory management alloc func
+*/
+#include <stdlib.h>
+
+#include "mod2.h"
+
+#include <omalloc.h>
+
+/* We define those, so that our values of
+   OM_TRACK and OM_CHECK are used  */
+void* operator new ( size_t size )
+{
+  void* addr;
+  if (!size) size = 1;
+  omTypeAlloc(void*, addr, size);
+  return addr;
+}
+
+void operator delete ( void* block )
+{
+  omfree( block );
+}
+
+void* operator new[] ( size_t size )
+{
+  void* addr;
+  if (! size) size = 1;
+  omTypeAlloc(void*, addr, size);
+  return addr;
+}
+
+void operator delete[] ( void* block )
+{
+  omfree( block );
+}
Index: kernel/mmalloc.h
===================================================================
--- kernel/mmalloc.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/mmalloc.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,26 @@
+#ifndef MMEMORY_H
+#define MMEMORY_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: mmalloc.h,v 1.1.1.1 2003-10-06 12:15:57 Singular Exp $ */
+/*
+* ABSTRACT: declaration of routines for memory stuff
+*/
+
+#include <stdlib.h>
+
+int mmInit(void);
+#undef reallocSize
+#undef freeSize
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+  void* reallocSize(void* old_addr, size_t old_size, size_t new_size);
+  void  freeSize(void* addr, size_t size);
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: kernel/mminit.cc
===================================================================
--- kernel/mminit.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/mminit.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,56 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: mminit.cc,v 1.1.1.1 2003-10-06 12:15:57 Singular Exp $ */
+/*
+* ABSTRACT: init of memory management
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mod2.h"
+#include "mmalloc.h"
+#include "structs.h"
+// this prevents the definition of malloc/free and macros
+// by omalloc
+#define OMALLOC_C
+#include "omalloc.h"
+
+#include <si_gmp.h>
+
+int mmIsInitialized=mmInit();
+
+extern "C"
+{
+  void omSingOutOfMemoryFunc()
+  {
+    fprintf(stderr, "\nerror: no more memory\n");
+    omPrintStats(stderr);
+    m2_end(14);
+    /* should never get here */
+    exit(1);
+  }
+}
+
+int mmInit( void )
+{
+  if(mmIsInitialized==0)
+  {
+#if defined(OMALLOC_USES_MALLOC) || defined(X_OMALLOC)
+    mp_set_memory_functions(omMallocFunc,omReallocSizeFunc,omFreeSizeFunc);
+#else
+    mp_set_memory_functions(malloc,reallocSize,freeSize);
+#endif
+    om_Opts.OutOfMemoryFunc = omSingOutOfMemoryFunc;
+#ifndef OM_NDEBUG
+    om_Opts.ErrorHook = dErrorBreak;
+#endif
+    omInitInfo();
+#ifdef OM_SING_KEEP
+    om_Opts.Keep = OM_SING_KEEP;
+#endif
+  }
+  mmIsInitialized=1;
+  return 1;
+}
Index: kernel/mmstd.c
===================================================================
--- kernel/mmstd.c	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/mmstd.c	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,50 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: mmstd.c,v 1.1.1.1 2003-10-06 12:15:57 Singular Exp $ */
+/*
+* ABSTRACT: standard version of C-memory management alloc func 
+* i.e. (malloc/realloc/free)
+*/
+
+#include "mod2.h"
+
+#define OM_NO_MALLOC_MACROS
+#ifdef ix86_Win
+#define OMALLOC_USES_MALLOC
+#endif
+#ifdef ppcMac_darwin
+#define OMALLOC_USES_MALLOC
+#endif
+#include "omalloc.h"
+
+// we provide these functions, so that the settings of OM_CHECK
+// and OM_TRACK are used, but only provide them if omalloc is not based
+// on them
+#ifndef OMALLOC_USES_MALLOC
+
+// define this so that all addr allocated there are marked 
+// as static, i.e. not metioned by omPrintUsedAddr
+#define OM_MALLOC_MARK_AS_STATIC
+#include <omalloc.c>
+#else
+#include <stdlib.h>
+void freeSize(void* addr, size_t size)
+{
+  if (addr) free(addr);
+}
+
+void* reallocSize(void* old_addr, size_t old_size, size_t new_size)
+{
+  if (old_addr && new_size)
+  {
+   return realloc(old_addr, new_size);
+  }
+  else 
+  {
+    freeSize(old_addr, old_size);
+    return malloc(new_size);
+  }
+}
+#endif
+
Index: kernel/mod2.h.in
===================================================================
--- kernel/mod2.h.in	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/mod2.h.in	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,633 @@
+/* -*-c++-*- */
+/*******************************************************************
+ *  Computer Algebra System SINGULAR
+ *
+ *  mod2.h: Main configuration file for Singular
+ *          DO NOT EDIT!
+ *
+ *  Version: $Id: mod2.h.in,v 1.1.1.1 2003-10-06 12:15:57 Singular Exp $
+ *******************************************************************/
+#ifndef MOD2_H
+#define MOD2_H
+
+/*******************************************************************
+ * Defines which are set by configure
+ ******************************************************************/
+/* Define to use dynamic linking */
+#undef HAVE_DL
+/* Define to use readline lib for fancy display: configure result */
+#undef HAVE_LIBREADLINE
+/* Define to use static readline lib for fancy display */
+#undef HAVE_READLINE
+/* define to use dynamic version of readline lib */
+#undef HAVE_DYN_RL
+/* Define to have dbm links */
+#undef HAVE_DBM
+/* Define to have smallgmp */
+#undef HAVE_SMALLGMP
+/* Define to have MP links */
+#undef HAVE_MPSR
+/* Define to have factory functionality added */
+#undef HAVE_FACTORY
+/* Define to have libfac functionality added */
+#undef HAVE_LIBFAC_P
+/* Define if you have stdc headers */
+#undef STDC_HEADERS
+/* Define if you have asm/sigcontext.h */
+#undef HAVE_ASM_SIGCONTEXT_H
+/* Define if you have sys/file.h */
+#undef HAVE_SYS_FILE_H
+/* Define if you have sys/stat.h */
+#undef HAVE_SYS_STAT_H
+/* Define if you have sys/param.h */
+#undef HAVE_SYS_PARAM_H
+/* Define if you have sys/file.h */
+#undef HAVE_SYS_TYPES_H
+/* Define if you have sys/ioctl.h */
+#undef HAVE_SYS_IOCTL_H
+/* Define if you have sys/time.h */
+#undef HAVE_SYS_TIME_H
+/* Define if you have sys/times.h */
+#undef HAVE_SYS_TIMES_H
+/* io header: */
+/* Define if you have termcap.h */
+#undef HAVE_TERMCAP_H
+/* Define if you have termios.h */
+#undef HAVE_TERMIOS_H
+/* Define if you have term.h */
+#undef HAVE_TERM_H
+/* Define if you have readline/history.h */
+#undef HAVE_READLINE_HISTORY_H
+/* Define if readline/readline.h is ok */
+#undef READLINE_READLINE_H_OK
+/* Define if time.h and sys/time.h can be included at the same time */
+#undef TIME_WITH_SYS_TIME
+/* Define if you have alloca.h */
+#undef HAVE_ALLOCA_H
+/* Define if you have pwd.h */
+#undef HAVE_PWD_H
+/* Define if you have unistd.h */
+#undef HAVE_UNISTD_H
+/* define if you have malloc.h */
+#undef HAVE_MALLOC_H
+/* define if you have pwd.h*/
+#undef HAVE_PWD_H
+/* Define if you have alloca */
+#undef HAVE_ALLOCA
+/* Define if you have getpagesize */
+#undef GETPAGESIZE
+/* Define if you have vprintf */
+#undef HAVE_VPRINTF
+/* Define if you have gettimeofday */
+#undef HAVE_GETTIMEOFDAY
+/* Define if you have atexit */
+#undef HAVE_ATEXIT
+/* Define if you have bcopy, bzero and bcmp
+   Linux needs that define! */
+#undef HAVE_BCOPY
+/* Define if sprintf does not return number of printed chars */
+#undef BSD_SPRINTF
+/* define if you have explicit C++ constructors */
+#undef HAVE_EXPLICIT_CONSTR
+/* Define if you have the getcwd function.  */
+#undef HAVE_GETCWD
+/* Define if you have the getwd function.  */
+#undef HAVE_GETWD
+/* Define if you have snprintf */
+#undef HAVE_VSNPRINTF
+/* Define if you have readlink */
+#undef HAVE_READLINK
+/* Define if you have usleep */
+#undef HAVE_USLEEP
+/* Define if you have sleep */
+#undef HAVE_SLEEP
+/* Define if you have setenv */
+#undef HAVE_SETENV
+/* Define if you have petpwnam */
+#undef HAVE_GETPWNAM
+/* Define if you have popen */
+#undef HAVE_POPEN
+/* Define sizeof(char) */
+#define SIZEOF_CHAR 1
+/* Define sizeof(short) */
+#define SIZEOF_SHORT 2
+/* Define sizeof(int) */
+#define SIZEOF_INT 4
+/* Define sizeof(long) */
+#define SIZEOF_LONG 4
+/* Define sizeof(void*) */
+#define SIZEOF_VOIDP 4
+/* Define sizeof(double) */
+#define SIZEOF_DOUBLE 8
+/* Define if your integer format is big endian */
+#undef WORDS_BIGENDIAN
+/* Define major version of Singular -- should be set in ../configure.in!!!*/
+#define SINGULAR_MAJOR_VERSION 0
+/* Define minor version of Singular -- should be set in ../configure.in!!! */
+#define SINGULAR_MINOR_VERSION 0
+/* Define sub version of Singular -- should be set in ../configure.in!!! */
+#define SINGULAR_SUB_VERSION 0
+/* Define version as a string */
+#define S_VERSION1 ""
+/* Define version date as a string */
+#define S_VERSION2 ""
+/* Define uname identifier as a string */
+#define S_UNAME ""
+/* Absolute pathname of root directory of Singular source */
+#define S_ROOT_DIR ""
+/* Define to use new namespaces techniks */
+#undef HAVE_NAMESPACES
+#undef HAVE_NS
+/* Define to enable dynamic module code */
+#undef HAVE_DYNAMIC_LOADING
+/* Define to enable plural */
+#undef HAVE_PLURAL
+
+/*******************************************************************
+ * Defines which are not set by configure
+ ******************************************************************/
+
+/* Default value for timer resolution in ticks per second */
+/* set to 10 for resolution of tenth of a second, etc */
+#define TIMER_RESOLUTION 1
+
+/* Undefine to disable the quote/eval of expressions */
+#define SIQ 1
+
+/* Define to enable TCL interface */
+#undef HAVE_TCL 
+
+/* Undefine to disable Gerhard's and Wilfried's fast and dirty std computations */
+#define FAST_AND_DIRTY
+#ifdef __MWERKS__
+/* includes for Metrowerks */
+#include "mod2.mwerks.h"
+#else
+/* works around a quirk in gcc in the generation of parser tables */
+#define INIT_BUG
+#endif
+
+/* eigenvalues */
+#ifndef HAVE_DYNAMIC_LOADING
+#define HAVE_EIGENVAL 1
+
+/* Gauss-Manin system */
+#define HAVE_GMS 1
+#endif
+
+/* linear algebra extensions from pcv.h/pcv.cc */
+#define HAVE_PCV 1
+
+// procedures to compute with units
+#define HAVE_UNITS
+
+/* Define to use old mechanismen for saving currRing with procedures
+ * Does not work with HAVE_NAMESPACES enabled
+ */
+#undef USE_IILOCALRING
+
+
+/* Define to use scanner when loading libraries */
+#define HAVE_LIBPARSER
+
+/*#define PROFILING*/
+#ifdef PROFILING
+#define PROFILER ,0,0
+#else
+#define PROFILER
+#endif
+
+/* Define to use gmp for rational arithmetic */
+#define HAVE_GMP
+
+/*******************************************************************
+ * Evaluate the set defines
+ ******************************************************************/
+/* FGLM needs factory */
+#ifdef HAVE_FACTORY
+#define HAVE_FGLM
+#endif
+
+/* Define if you want fglm for homogeneous case */
+#ifdef HAVE_FGLM
+#undef HAVE_FGLM_HOME
+#endif
+
+/* Spectrum needs GMP */
+#ifdef HAVE_GMP
+#define HAVE_SPECTRUM 1
+#endif
+
+/* Undefine to disable real time measurments  */
+#ifdef HAVE_GETTIMEOFDAY
+#if ! defined(__MWERKS__) && ! defined(MSDOS)
+#define HAVE_RTIMER
+#else
+#undef HAVE_RTIMER
+#endif
+#endif
+
+#if SIZEOF_VOIDP == 8
+/* SIZEOF_LONG == SIZEOF_VOIDP is guaranteed by configure */
+#define ALIGN_8
+#define LOG_SIZEOF_LONG  3
+#define LOG_SIZEOF_VOIDP 3
+#else
+#define LOG_SIZEOF_LONG  2
+#define LOG_SIZEOF_VOIDP 2
+#endif
+
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
+#define BIT_SIZEOF_LONG CHAR_BIT*SIZEOF_LONG
+
+#define SINGULAR_VERSION (SINGULAR_MAJOR_VERSION*1000 + SINGULAR_MINOR_VERSION*100 + SINGULAR_SUB_VERSION)
+
+#if SIZEOF_EXPONENT == 1
+#define MAX_EXPONENT 0x7f
+#define MAX_COMPONENT 0xff
+#elif SIZEOF_EXPONENT == 2
+#define MAX_EXPONENT 0x7fff
+#define MAX_COMPONENT 0xffff
+#else /* SIZEOF_EXPONENT == 4 */
+#define MAX_EXPONENT 0x7fffffff
+#define MAX_COMPONENT 0xffffffff
+#endif
+
+/*******************************************************************
+ * Miscellanous Defines
+ ******************************************************************/
+/* Under HPUX 9, system(...) returns -1 if SIGCHLD does not equal
+   SIG_DFL. However, if it stays at SIG_DFL we get zombie processes
+   for terminated childs generated by fork. Therefors some special treatment 
+   is necessary */
+#ifdef HPUX_9
+#include <stdlib.h>
+#define system hpux9_system
+#ifdef __cplusplus
+extern "C" {
+#endif
+int hpux9_system(const char* system);
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#ifndef HAVE_LIBPARSER
+#  undef YYLPDEBUG
+#else
+#  define YYLPDEBUG 1
+#endif
+
+#ifndef FALSE
+#define FALSE       0
+#endif
+
+#ifndef TRUE
+#define TRUE        1
+#endif
+
+#ifndef NULL
+#define NULL        (0)
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+#define HALT() m2_end(2)
+
+#define memcpy4 memcpy
+
+/* define OLD_RES for res/sres/mres(i,j,k) */
+#undef OLD_RES
+
+/* the maximal ascii length of an int number + 1 = 11 for 32 bit int */
+#define MAX_INT_LEN 11
+#define MAX_INT_VAL 0x7fffffff
+
+#ifdef DO_PROFILE
+/* define to enable explicit profiling of some crucial inline
+ * routines and defines  */
+#undef DO_DEEP_PROFILE
+#endif
+
+#define buildin_rand 1
+
+/* define to enable assume */
+#ifndef HAVE_ASSUME
+#undef HAVE_ASSUME
+#endif
+
+/* define LINKAGE to "extern C" if compiling for shared libs */
+#ifndef LINKAGE
+#if defined(PIC)
+#define LINKAGE extern "C"
+#else
+#define LINKAGE
+#endif
+#endif
+
+
+/*******************************************************************
+ * DEBUG OPTIONS
+ * -- only significant for for compiling without -DNDEBUG
+ * -- you better know what your are doing, if you touch this
+ ******************************************************************/
+#ifndef NDEBUG
+
+/* undefine to enable inline */
+#define NO_INLINE
+
+/* undefine to disable assume -- should normally be defined for NDEBUG */
+#define HAVE_ASSUME
+
+/* undef PDEBUG to disable checks of polys
+
+ define PDEBUG to
+  0 for enabling pTest
+  1 plus tests in Level 1 poly routines (operations on monomials)
+  2 plus tests in Level 2 poly routines (operations on single exponents)
+ -- see also polys.h for more info
+
+ NOTE: you can set the value of PDEBUG on a per-file basis, before
+       including mod2.h, provided ! PDEBUG is defined in mod2.h E.g.:
+
+       #define PDEBUG 2
+       #include "mod2.h"
+       ...
+
+       makes sure that all poly operations in your file are done with 
+       PDEBUG == 2
+ To break after an error occured, set a debugger breakpoint on
+ dErrorBreak. 
+*/
+#ifndef PDEBUG
+#define PDEBUG 0
+#endif
+
+/* define MDEBUG to enable memory checks */
+#define MDEBUG 0
+
+#ifdef MDEBUG
+/* If ! defined(OM_NDEBUG) and (defined(OM_TRACK) or defined(OM_CHECK)
+   then omDebug routines are used for memory allocation/free:
+
+   The omDebug routines are controlled by the values of OM_TRACK, OM_CHECK
+   and OM_KEEP.  There meaning is roughly as follows:
+   OM_TRACK: strored with address                              : extra space
+     0     : no additional info is stored                      : 0
+     1     : file:line of location where address was allocated : 1 word
+     2     : plus backtrace of stack where adress was allocated: 6 words
+     3     : plus size/bin info and front-, and back padding   : 9 words
+     4     : plus file:line of location where adress was freed : 10 words
+     5     : plus backtrace of stack where adress was allocated: 15 words
+   OM_CHECK: checks done
+     0     : no checks
+     1     : constant-time checks: i.e. addr checks only
+     2     : plus linear-time checks and constant related bin check
+     3     : plus quadratic-time checks and linear-time related bin checks and
+             constant time all memory checks
+     4     : and so on
+     ==> for OM_CHECK >= 3 it gets rather slow
+   OM_KEEP:  determines whether addresses are really freed  (
+     0     : addresses are really freed
+     1     : addresses are only marked as free and not really freed.
+
+   OM_CHECK, OM_TRACK, and OM_KEEP can be set on a per-file basis 
+   (as can OM_NDEBUG),  e.g.:
+     #define OM_CHECK 3
+     #define OM_TRACK 5
+     #define OM_KEEP  1
+     #include "mod2.h"
+     #include "omalloc.h"
+   ensures that all memory allocs/free in this file are done with 
+   OM_CHECK==3 and OM_TRACK==5, and that all addresses allocated/freed 
+   in this file are only marked as free and never really freed.
+ 
+   To set OM_CHECK, OM_TRACK and OM_KEEP under dynamic scope, set 
+   om_Opts.MinCheck, om_Opts.MinTrack to the respectiv values and 
+   om_Opts.Keep to the number of addresses which are kept before they are 
+   actually freed. E.g.:
+     int check=om_Opts.MinCheck, track=om_Opts.MinTrack, keep= m_OPts.Keep;
+     om_Opts.MinCheck = 3; om_Opts.MinTrack = 5; omOpts.Keep = LONG_MAX;
+     ExternalRoutine();
+     om_Opts.MinCheck = check; omOpts.MinTrack = track; omOpts.Keep = keep;
+   ensures that all calls omDebug routines  occuring during the computation of
+   ExternalRoutine() are done with OM_CHECK==3 and OM_TRACK==5, and 
+   calls to omFree only mark addresses as free and not really free them.
+
+   Furthermore, the value of OM_SING_KEEP (resp. om_Opts.Keep) specifies 
+   how many addresses are kept before they are actually freed, independently 
+   of the value of OM_KEEP.
+
+   Some tips on possible values of OM_TRACK, OM_CHECK, OM_KEEP:
+   + To find out about an address that has been freed twice, first locate the
+     file(s) where the error occured, and then at the beginning of these files:
+       #define OM_CHECK 3
+       #define OM_TRACK 5
+       #define OM_KEEP  1
+       #include "mod2.h"
+       #include "omalloc.h"
+     Under dynamic scope, do (e.g., from within the debugger):
+       om_Opts.MinCheck = 3; om_Opts.MinTrack = 5; omOpts.Keep = LONG_MAX;
+   + to find out where "memory corruption" occured, increase value of 
+     OM_CHECK - the higher this value is, the more consistency checks are 
+     done (However a value > 3 checks the entire memory each time an omalloc 
+     routine is used!)
+   
+   Some more tips on the usage of omalloc:
+   + omAlloc*, omRealloc*, omFree*, omCheck* omDebug* omTest* rotuines 
+     assume that sizes are > 0 and pointers are != NULL
+   + omalloc*, omrealloc*, omfree* omcheck*, omdebug* omtest* routines allow
+     NULL pointers and sizes == 0
+   + You can safely use any free/realloc routine in combination with any alloc 
+     routine (including the debug versions): E.g., an address allocated with
+     omAllocBin can be freed with omfree, or an adress allocated with 
+     om(Debug)Alloc can be freed with omfree, or omFree, or omFreeSize, etc.
+     However, keep in mind that the efficiency decreases from 
+     Bin over Size to General routines (i.e., omFreeBin is more efficient than
+     omFreeSize which is more efficient than omFree, likewise with the alloc
+     routines).
+   + if OM_CHECK is undefined or 0, then all omCheck routines do nothing
+   + if OM_CHECK and OM_TRACK are both undefined (or 0), or if OM_NDEBUG is 
+     defined, then the "real" alloc/realloc/free macros are used, and all 
+     omTest, omDebug and omCheck routines are undefined
+   + to break after an omError occured within a debugger, 
+     set a breakpoint on dErrorBreak
+   + to do checks from within the debugger, or to do checks with explicit 
+     check level, use omTest routines.
+*/
+
+/* by default, store alloc info and file/line where addr was freed */
+#ifndef OM_TRACK
+#define OM_TRACK 4
+#endif
+/* only do constant-time memory checks */
+#ifndef OM_CHECK
+#define OM_CHECK 1
+#endif
+/* Do actually free memory: 
+   (be careful: if this is set, memory is never really freed, 
+    but only marked as free) */
+#ifndef OM_KEEP
+#define OM_KEEP 0
+#endif
+/* but only after you have freed 1000 more addresses 
+   (this is actually independent of the value of OM_KEEP and used
+   to initialize om_Opts.Keep) */
+#ifndef OM_SING_KEEP
+#define OM_SING_KEEP 1000
+#endif
+
+#endif /* MDEBUG */
+
+
+/* undef KDEBUG for check of data during std computations 
+ *
+ * define KDEBUG to
+ * 0 for basic tests
+ * 1 for tests in kSpoly 
+ * NOTE: You can locally enable tests in kspoly by setting the 
+ *       define at the beginning of kspoly.cc
+ */
+#define KDEBUG 0
+
+/* define LDEBUG checking numbers, undefine otherwise */
+#define LDEBUG
+/* define RDEBUG checking rings (together with TRACE=9) */
+#define RDEBUG
+/* define TEST for non time critical tests, undefine otherwise */
+#define TEST
+
+/* #define PAGE_TEST */
+
+/* define YYDEBUG 1 for debugging bison texts, 0 otherwise */
+#define YYDEBUG 1
+
+/* Undefine to disable debugging of MP stuff */
+#ifdef HAVE_MPSR
+#define MPSR_DEBUG
+#endif
+
+
+#ifdef TEST
+#ifndef buildin_rand
+#define buildin_rand 1
+#endif
+#endif
+
+/* define SPECTRUM_DEBUG and SPECTRUM_PRINT for debugging the spectrum code */
+/* define SPECTRUM_IOSTREAM to use C++ iostream for error messages          */
+
+/* #define SPECTRUM_DEBUG */
+/* #define SPECTRUM_PRINT */
+#undef  SPECTRUM_IOSTREAM
+
+#ifdef  SPECTRUM_DEBUG
+#define MULTICNT_DEBUG
+#define GMPRAT_DEBUG
+#define KMATRIX_DEBUG
+#define SPLIST_DEBUG
+#define NPOLYGON_DEBUG
+#define SEMIC_DEBUG
+#endif
+
+#ifdef  SPECTRUM_PRINT
+#define MULTICNT_PRINT
+#define GMPRAT_PRINT
+#define KMATRIX_PRINT
+#define SPLIST_PRINT
+#define NPOLYGON_PRINT
+#define SEMIC_PRINT
+#endif
+
+#ifdef  SPECTRUM_IOSTREAM
+#define MULTICNT_IOSTREAM
+#define GMPRAT_IOSTREAM
+#define KMATRIX_IOSTREAM
+#define SPLIST_IOSTREAM
+#define NPOLYGON_IOSTREAM
+#define SEMIC_IOSTREAM
+#endif
+
+
+#else /* not NDEBUG **************************************************** */
+
+#define NO_PDEBUG
+
+/* define YYDEBUG 1 for debugging bison texts, 0 otherwise */
+#define YYDEBUG 0
+
+#endif /* not NDEBUG */
+
+#ifdef HAVE_NAMESPACES
+#  undef USE_IILOCALRING
+#endif
+
+/*******************************************************************
+ *
+ * assume(x) -- a handy macro for assumptions
+ *
+ ******************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+// routine which is used to report the error
+// returns 0
+extern int dReportError(const char* fmt, ...);
+// within a debugger, set a breakpoint on dErrorBreak
+// which is called after the error has been reported
+extern void dErrorBreak();
+#ifdef __cplusplus
+}
+#endif
+
+#ifndef HAVE_ASSUME
+#define assume(x) ((void) 0)
+#define r_assume(x) ((void) 0)
+#else /* ! HAVE_ASSUME */
+
+#define assume_violation(s,f,l) \
+  dReportError("assume violation at %s:%d condition: %s", f,l,s)
+
+#define assume(x)   _assume(x, __FILE__, __LINE__)
+#define r_assume(x) _r_assume(x, __FILE__, __LINE__)
+
+#define _assume(x, f, l)                        \
+do                                              \
+{                                               \
+  if (! (x))                                    \
+  {                                             \
+    assume_violation(#x, f, l);                 \
+  }                                             \
+}                                               \
+while (0)
+
+#define _r_assume(x, f, l)                      \
+do                                              \
+{                                               \
+  if (! (x))                                    \
+  {                                             \
+    assume_violation(#x, f, l);                 \
+    return 0;                                   \
+  }                                             \
+}                                               \
+while (0)
+#endif /* HAVE_ASSUME */
+
+/* do have RDEBUG, unless we are doing the very real thing */
+#ifdef HAVE_ASSUME
+#ifndef RDEBUG
+#define RDEBUG 
+#endif
+#endif
+
+#endif /* MOD2_H  */
Index: kernel/mod_raw.cc
===================================================================
--- kernel/mod_raw.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/mod_raw.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,409 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: mod_raw.cc,v 1.1.1.1 2003-10-06 12:15:57 Singular Exp $ */
+/*
+ * ABSTRACT: machine depend code for dynamic modules
+ *
+ * Provides: dynl_open()
+ *           dynl_sym()
+ *           dynl_error()
+ *           dunl_close()
+*/
+
+#include <stdio.h>
+
+#include "mod2.h"
+#include "static.h"
+#ifdef HAVE_STATIC
+#undef HAVE_DL
+#endif
+
+#if defined(HAVE_DL)
+#include "mod_raw.h"
+#include "febase.h"
+
+/*****************************************************************************
+ *
+ * General section
+ * These are just wrappers around the repsective dynl_* calls 
+ * which look for the binary in the bin_dir of Singular and ommit warnings if
+ * somethings goes wrong
+ *
+ *****************************************************************************/
+static BOOLEAN warn_handle = FALSE;
+static BOOLEAN warn_proc = FALSE;
+#ifndef DL_TAIL
+#define DL_TAIL "so"
+#endif
+
+void* dynl_open_binary_warn(char* binary_name, const char* msg)
+{
+  void* handle = NULL;
+  const char* bin_dir = feGetResource('b');
+  if (bin_dir != NULL)
+  {
+    char path_name[MAXPATHLEN];
+    sprintf(path_name, "%s%s%s.%s", bin_dir, DIR_SEPP, binary_name, 
+            DL_TAIL);
+    handle = dynl_open(path_name);
+    if (handle == NULL && ! warn_handle)
+    {
+      Warn("Could not open dynamic library: %s", path_name);
+      Warn("Error message from system: %s", dynl_error());
+      if (msg != NULL) Warn("%s", msg);
+      Warn("See the INSTALL section in the Singular manual for details.");
+      warn_handle = TRUE;
+    }
+  }
+  return  handle;
+}
+
+void* dynl_sym_warn(void* handle, char* proc, const char* msg)
+{
+  void *proc_ptr = NULL;
+  if (handle != NULL)
+  {
+    proc_ptr = dynl_sym(handle, proc);
+    if (proc_ptr == NULL && ! warn_proc)
+    {
+      Warn("Could load a procedure from a dynamic library");
+      Warn("Error message from system: %s", dynl_error());
+      if (msg != NULL) Warn("%s", msg);
+      Warn("See the INSTALL section in the Singular manual for details.");
+      warn_proc = TRUE;
+    }
+  }
+  return proc_ptr;
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*****************************************************************************
+ * SECTION generic Linux: ix86-linux / alpha-linux / IA64-linux /x86_64_Linux*
+ *****************************************************************************/
+#if defined(ix86_Linux)
+#define HAVE_ELF_SYSTEM
+#endif
+
+#if defined(ix86_Linux_libc5)
+#define HAVE_ELF_SYSTEM
+#endif
+
+#if defined(DecAlpha_Linux)
+#define HAVE_ELF_SYSTEM
+#endif
+
+#if defined(IA64_Linux)
+#define HAVE_ELF_SYSTEM
+#endif
+
+#if defined(x86_64_Linux)
+#define HAVE_ELF_SYSTEM
+#endif
+
+#if defined(HAVE_ELF_SYSTEM)
+#include <dlfcn.h>
+
+static void* kernel_handle = NULL;
+void *dynl_open(
+  char *filename    /* I: filename to load */
+  )
+{
+  return(dlopen(filename, RTLD_NOW|RTLD_GLOBAL));
+}
+
+void *dynl_sym(void *handle, char *symbol)
+{
+  if (handle == DYNL_KERNEL_HANDLE)
+  {
+    if (kernel_handle == NULL)
+      kernel_handle = dynl_open(NULL);
+    handle = kernel_handle;
+  }
+  return(dlsym(handle, symbol));
+}
+
+int dynl_close (void *handle)
+{
+  return(dlclose (handle));
+}
+
+const char *dynl_error()
+{
+  return(dlerror());
+}
+#endif /* Linux */
+
+/*****************************************************************************
+ * SECTION HPUX-9/10                                                         *
+ *****************************************************************************/
+#if defined(HPUX_9) || defined(HPUX_10)
+#include <dl.h>
+
+typedef char *((*func_ptr) ());
+
+void *dynl_open(char *filename)
+{
+  shl_t           handle = shl_load(filename, BIND_DEFERRED, 0);
+
+  return ((void *) handle);
+}
+
+void *dynl_sym(void *handle, char *symbol)
+{
+  func_ptr        f;
+  
+  if (handle == DYNL_KERNEL_HANDLE)
+    handle = PROG_HANDLE;
+  
+  if (shl_findsym((shl_t *) & handle, symbol, TYPE_PROCEDURE, &f) == -1)
+  {
+    if (shl_findsym((shl_t *) & handle, symbol, TYPE_UNDEFINED, &f) == -1)
+    {
+      f = (func_ptr) NULL;
+    }
+  }
+  return ((void *)f);
+}
+
+int dynl_close (void *handle)
+{
+  shl_unload((shl_t) handle);
+  return(0);
+}
+
+const char *dynl_error()
+{
+  static char errmsg[] = "shl_load failed";
+
+  return errmsg;
+}
+#endif /* HPUX_9  or HPUX_10 */
+
+/*****************************************************************************
+ * SECTION 68k-MPW                                                           *
+ *****************************************************************************/
+#ifdef MPW
+/* #    include <> */
+
+void *dynl_open(char *filename)
+{
+  return(NULL);
+}
+
+void *dynl_sym(void *handle, char *symbol)
+{
+  return(NULL);
+}
+
+int dynl_close (void *handle)
+{
+  return(0);
+}
+
+const char *dynl_error()
+{
+  static char errmsg[] = "support for dynamic loading not implemented";
+
+  return errmsg;
+}
+#  endif /* 68k_MPW */
+
+
+/*****************************************************************************
+ * SECTION AIX-4                                                             *
+ *****************************************************************************/
+#ifdef AIX_4
+/* #    include <> */
+
+void *dynl_open(char *filename)
+{
+  return(NULL);
+}
+
+void *dynl_sym(void *handle, char *symbol)
+{
+  return(NULL);
+}
+
+int dynl_close (void *handle)
+{
+  return(0);
+}
+
+const char *dynl_error()
+{
+  static char errmsg[] = "support for dynamic loading not implemented";
+
+  return errmsg;
+}
+#  endif /* AIX_4 */
+
+/*****************************************************************************
+ * SECTION IRIX-6                                                            *
+ *****************************************************************************/
+#ifdef IRIX_6
+#include <dlfcn.h>
+static void* kernel_handle = NULL;
+void *dynl_open( char *filename)
+{
+  return(dlopen(filename, RTLD_NOW|RTLD_GLOBAL));
+}
+
+void *dynl_sym(void *handle, char *symbol)
+{
+  if (handle == DYNL_KERNEL_HANDLE)
+  {
+    if (kernel_handle == NULL)
+      kernel_handle = dynl_open(NULL);
+    handle = kernel_handle;
+  }
+  return(dlsym(handle, symbol));
+}
+
+int dynl_close (void *handle)
+{
+  return(dlclose (handle));
+}
+
+const char *dynl_error()
+{
+  return(dlerror());
+}
+#  endif /* IRIX_6 */
+
+/*****************************************************************************
+ * SECTION Sun3OS-4                                                          *
+ *****************************************************************************/
+#ifdef Sun3OS_4
+/* #    include <> */
+
+void *dynl_open(char *filename)
+{
+  return(NULL);
+}
+
+void *dynl_sym(void *handle, char *symbol)
+{
+  return(NULL);
+}
+
+int dynl_close (void *handle)
+{
+  return(0);
+}
+
+const char *dynl_error()
+{
+  static char errmsg[] = "support for dynamic loading not implemented";
+
+  return errmsg;
+}
+#endif /* Sun3OS_4 */
+
+/*****************************************************************************
+ * SECTION SunOS-4                                                         *
+ *****************************************************************************/
+#if defined(SunOS_4)
+/* #    include <> */
+
+void *dynl_open(char *filename)
+{
+  return(NULL);
+}
+
+void *dynl_sym(void *handle, char *symbol)
+{
+  return(NULL);
+}
+
+int dynl_close (void *handle)
+{
+  return(0);
+}
+
+const char *dynl_error()
+{
+  static char errmsg[] = "support for dynamic loading not implemented";
+
+  return errmsg;
+}
+#endif /* SunOS_4 */
+ 
+/*****************************************************************************
+ * SECTION SunOs-5
+ *****************************************************************************/
+#if defined(SunOS_5)
+#include <dlfcn.h>
+
+static void* kernel_handle = NULL;
+void *dynl_open(
+  char *filename    /* I: filename to load */
+  )
+{
+  return(dlopen(filename, RTLD_NOW|RTLD_GLOBAL));
+}
+
+void *dynl_sym(void *handle, char *symbol)
+{
+  if (handle == DYNL_KERNEL_HANDLE)
+  {
+    if (kernel_handle == NULL)
+      kernel_handle = dynl_open(NULL);
+    handle = kernel_handle;
+  }
+  return(dlsym(handle, symbol));
+}
+
+int dynl_close (void *handle)
+{
+  return(dlclose (handle));
+}
+
+const char *dynl_error()
+{
+  return(dlerror());
+}
+#endif /* SunOS_5 */
+
+/*****************************************************************************
+ * SECTION ix86-Win                                                          *
+ *****************************************************************************/
+// is defined externally in sing_win.cc
+
+/*****************************************************************************
+ * SECTION ppc-MPW                                                           *
+ *****************************************************************************/
+#ifdef ppc_MPW
+/* #    include <> */
+
+void *dynl_open(char *filename)
+{
+  return(NULL);
+}
+
+void *dynl_sym(void *handle, char *symbol)
+{
+  return(NULL);
+}
+
+int dynl_close (void *handle)
+{
+  return(0);
+}
+
+const char *dynl_error()
+{
+  static char errmsg[] = "support for dynamic loading not implemented";
+  return errmsg;
+}
+#  endif /* ppc_MPW */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAVE_DL */
Index: kernel/mod_raw.h
===================================================================
--- kernel/mod_raw.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/mod_raw.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,38 @@
+#ifndef MOD_RAW_H
+#define MOD_RAW_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: mod_raw.h,v 1.1.1.1 2003-10-06 12:15:57 Singular Exp $ */
+/*
+ * ABSTRACT: machine depend code for dynamic modules
+ *
+ * Provides: dynl_open()
+ *           dynl_sym()
+ *           dynl_error()
+ *           dunl_close()
+*/
+
+#if defined(HAVE_DL)
+#ifdef __cplusplus
+void* dynl_open_binary_warn(char* binary_name, const char* msg = NULL );
+void* dynl_sym_warn(void* handle, char* proc, const char* msg = NULL );
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void *       dynl_open(char *filename);
+// if handle == DYNL_KERNEL_HANDLE, then symbol is searched for
+// in kernel of program
+#define DYNL_KERNEL_HANDLE ((void*) 0x1)
+void *       dynl_sym(void *handle, char *symbol);
+int          dynl_close (void *handle);
+const char * dynl_error();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAVE_DL */
+#endif /* MOD_RAW_H */
Index: kernel/modulop.cc
===================================================================
--- kernel/modulop.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/modulop.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,597 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: modulop.cc,v 1.1.1.1 2003-10-06 12:15:55 Singular Exp $ */
+/*
+* ABSTRACT: numbers modulo p (<=32003)
+*/
+
+#include <string.h>
+#include "mod2.h"
+#include <mylimits.h>
+#include "structs.h"
+#include "febase.h"
+#include "omalloc.h"
+#include "numbers.h"
+#include "longrat.h"
+#include "mpr_complex.h"
+#include "ring.h"
+#include "modulop.h"
+
+long npPrimeM=0;
+int npGen=0;
+long npPminus1M=0;
+long npMapPrime;
+
+#ifdef HAVE_DIV_MOD
+CARDINAL *npInvTable=NULL;
+#endif
+
+#if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD)
+CARDINAL *npExpTable=NULL;
+CARDINAL *npLogTable=NULL;
+#endif
+
+
+BOOLEAN npGreaterZero (number k)
+{
+  int h = (int) k;
+  return ((int)h !=0) && (h <= (npPrimeM>>1));
+}
+
+//unsigned long npMultMod(unsigned long a, unsigned long b)
+//{
+//  unsigned long c = a*b;
+//  c = c % npPrimeM;
+//  assume(c == (unsigned long) npMultM((number) a, (number) b));
+//  return c;
+//}
+
+number npMult (number a,number b)
+{
+  if (((long)a == 0) || ((long)b == 0))
+    return (number)0;
+  else
+    return npMultM(a,b);
+}
+
+/*2
+* create a number from int
+*/
+number npInit (int i)
+{
+  long ii=i;
+  while (ii <  0)                    ii += npPrimeM;
+  while ((ii>1) && (ii >= npPrimeM)) ii -= npPrimeM;
+  return (number)ii;
+}
+
+/*2
+* convert a number to int (-p/2 .. p/2)
+*/
+int npInt(number &n)
+{
+  if ((long)n > (npPrimeM >>1)) return (int)((long)n -npPrimeM);
+  else                          return (int)n;
+}
+
+number npAdd (number a, number b)
+{
+  return npAddM(a,b);
+}
+
+number npSub (number a, number b)
+{
+  return npSubM(a,b);
+}
+
+BOOLEAN npIsZero (number  a)
+{
+  return 0 == (long)a;
+}
+
+BOOLEAN npIsOne (number a)
+{
+  return 1 == (long)a;
+}
+
+BOOLEAN npIsMOne (number a)
+{
+  return ((npPminus1M == (long)a)&&((long)1!=(long)a));
+}
+
+#ifdef HAVE_DIV_MOD
+#if 1 //ifdef HAVE_NTL // in ntl.a
+//extern void XGCD(long& d, long& s, long& t, long a, long b);
+#include <NTL/ZZ.h>
+#ifdef NTL_CLIENT
+NTL_CLIENT
+#endif
+#else
+void XGCD(long& d, long& s, long& t, long a, long b)
+{
+   long  u, v, u0, v0, u1, v1, u2, v2, q, r;
+
+   long aneg = 0, bneg = 0;
+
+   if (a < 0) {
+      a = -a;
+      aneg = 1;
+   }
+
+   if (b < 0) {
+      b = -b;
+      bneg = 1;
+   }
+
+   u1=1; v1=0;
+   u2=0; v2=1;
+   u = a; v = b;
+
+   while (v != 0) {
+      q = u / v;
+      r = u % v;
+      u = v;
+      v = r;
+      u0 = u2;
+      v0 = v2;
+      u2 =  u1 - q*u2;
+      v2 = v1- q*v2;
+      u1 = u0;
+      v1 = v0;
+   }
+
+   if (aneg)
+      u1 = -u1;
+
+   if (bneg)
+      v1 = -v1;
+
+   d = u;
+   s = u1;
+   t = v1;
+}
+#endif
+
+long InvMod(long a)
+{
+   long d, s, t;
+
+   XGCD(d, s, t, a, npPrimeM);
+   assume (d == 1);
+   if (s < 0)
+      return s + npPrimeM;
+   else
+      return s;
+}
+#endif
+
+inline number npInversM (number c)
+{
+#ifndef HAVE_DIV_MOD
+  return (number)npExpTable[npPminus1M - npLogTable[(long)c]];
+#else
+  long inv=npInvTable[(long)c];
+  if (inv==0)
+  {
+    inv=InvMod((long)c);
+    npInvTable[(long)c]=inv;
+  }
+  return (number)inv;
+#endif
+}
+
+number npDiv (number a,number b)
+{
+  if ((long)a==0)
+    return (number)0;
+#ifndef HAVE_DIV_MOD
+  else if ((long)b==0)
+  {
+    WerrorS("div by 0");
+    return (number)0;
+  }
+  else
+  {
+    int s = npLogTable[(long)a] - npLogTable[(long)b];
+    if (s < 0)
+      s += npPminus1M;
+    return (number)npExpTable[s];
+  }
+#else
+  number inv=npInversM(b);
+  return npMultM(a,inv);
+#endif
+}
+number  npInvers (number c)
+{
+  if ((long)c==0)
+  {
+    WerrorS("1/0");
+    return (number)0;
+  }
+  return npInversM(c);
+}
+
+number npNeg (number c)
+{
+  if ((long)c==0) return c;
+  return npNegM(c);
+}
+
+BOOLEAN npGreater (number a,number b)
+{
+  //return (long)a != (long)b;
+  return (long)a > (long)b;
+}
+
+BOOLEAN npEqual (number a,number b)
+{
+//  return (long)a == (long)b;
+  return npEqualM(a,b);
+}
+
+void npWrite (number &a)
+{
+  if ((long)a > (npPrimeM >>1)) StringAppend("-%d",(int)(npPrimeM-((long)a)));
+  else                          StringAppend("%d",(int)a);
+}
+
+void npPower (number a, int i, number * result)
+{
+  if (i==0)
+  {
+    //npInit(1,result);
+    *(long *)result = 1;
+  }
+  else if (i==1)
+  {
+    *result = a;
+  }
+  else
+  {
+    npPower(a,i-1,result);
+    *result = npMultM(a,*result);
+  }
+}
+
+char* npEati(char *s, int *i)
+{
+
+  if (((*s) >= '0') && ((*s) <= '9'))
+  {
+    (*i) = 0;
+    do
+    {
+      (*i) *= 10;
+      (*i) += *s++ - '0';
+      if ((*i) >= (MAX_INT_VAL / 10)) (*i) = (*i) % npPrimeM;
+    }
+    while (((*s) >= '0') && ((*s) <= '9'));
+    if ((*i) >= npPrimeM) (*i) = (*i) % npPrimeM;
+  }
+  else (*i) = 1;
+  return s;
+}
+
+char * npRead (char *s, number *a)
+{
+  int z;
+  int n=1;
+
+  s = npEati(s, &z);
+  if ((*s) == '/')
+  {
+    s++;
+    s = npEati(s, &n);
+  }
+  if (n == 1)
+    *a = (number)z;
+  else 
+#ifdef NV_OPS
+    if (npPrimeM>NV_MAX_PRIME)
+      *a = nvDiv((number)z,(number)n);
+    else
+#endif    
+      *a = npDiv((number)z,(number)n);
+  return s;
+}
+
+/*2
+* the last used charcteristic
+*/
+//int npGetChar()
+//{
+//  return npPrimeM;
+//}
+
+/*2
+* set the charcteristic (allocate and init tables)
+*/
+
+void npSetChar(int c, ring r)
+{
+//  int i, w;
+
+//  if (c==npPrimeM) return;
+  if ((c>1) || (c<(-1)))
+  {
+    if (c>1) npPrimeM = c;
+    else     npPrimeM = -c;
+    npPminus1M = npPrimeM - 1;
+#ifdef HAVE_DIV_MOD
+    npInvTable=r->cf->npInvTable;
+#endif
+#if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD)
+    npExpTable=r->cf->npExpTable;
+    npLogTable=r->cf->npLogTable;
+    npGen = npExpTable[1];
+#endif
+  }
+  else
+  {
+    npPrimeM=0;
+#ifdef HAVE_DIV_MOD
+    npInvTable=NULL;
+#endif
+#if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD)
+    npExpTable=NULL;
+    npLogTable=NULL;
+#endif
+  }
+}
+
+void npInitChar(int c, ring r)
+{
+  int i, w;
+
+  if ((c>1) || (c<(-1)))
+  {
+    if (c>1) r->cf->npPrimeM = c;
+    else     r->cf->npPrimeM = -c;
+    r->cf->npPminus1M = r->cf->npPrimeM - 1;
+#ifdef NV_OPS
+    if (r->cf->npPrimeM <=NV_MAX_PRIME)
+#endif
+    {
+#if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD)
+      r->cf->npExpTable=(CARDINAL *)omAlloc( r->cf->npPrimeM*sizeof(CARDINAL) );
+      r->cf->npLogTable=(CARDINAL *)omAlloc( r->cf->npPrimeM*sizeof(CARDINAL) );
+      r->cf->npExpTable[0] = 1;
+      r->cf->npLogTable[0] = 0;
+      if (r->cf->npPrimeM > 2)
+      {
+        w = 1;
+        loop
+        {
+          r->cf->npLogTable[1] = 0;
+          w++;
+          i = 0;
+          loop
+          {
+            i++;
+            r->cf->npExpTable[i] =(int)(((long)w * (long)r->cf->npExpTable[i-1])
+                                 % r->cf->npPrimeM);
+            r->cf->npLogTable[r->cf->npExpTable[i]] = i;
+            if (/*(i == npPrimeM - 1 ) ||*/ (r->cf->npExpTable[i] == 1))
+              break;
+          }
+          if (i == r->cf->npPrimeM - 1)
+            break;
+        }
+      }
+      else
+      {
+        r->cf->npExpTable[1] = 1;
+        r->cf->npLogTable[1] = 0;
+      }
+#endif
+#ifdef HAVE_DIV_MOD
+      r->cf->npInvTable=(CARDINAL*)omAlloc0( r->cf->npPrimeM*sizeof(CARDINAL) );
+#endif
+    }
+  }
+  else
+  {
+    WarnS("nInitChar failed");
+  }
+}
+
+#ifdef LDEBUG
+BOOLEAN npDBTest (number a, char *f, int l)
+{
+  if (((long)a<0) || ((long)a>npPrimeM))
+  {
+    return FALSE;
+  }
+  return TRUE;
+}
+#endif
+
+number npMap0(number from)
+{
+  return npInit(nlModP(from,npPrimeM));
+}
+
+number npMapP(number from)
+{
+  long i = (long)from;
+  if (i>npMapPrime/2)
+  {
+    i-=npMapPrime;
+    while (i < 0) i+=npPrimeM;
+  }
+  i%=npPrimeM;
+  return (number)i;
+}
+
+static number npMapLongR(number from)
+{
+  gmp_float *ff=(gmp_float*)from;
+  mpf_t *f=ff->_mpfp();
+  number res;
+  lint *dest,*ndest;
+  int size,i;
+  int e,al,bl,iz,in;
+  mp_ptr qp,dd,nn;
+
+  size = (*f)[0]._mp_size;
+  if (size == 0)
+    return npInit(0);
+  if(size<0)
+    size = -size;
+
+  qp = (*f)[0]._mp_d;
+  while(qp[0]==0)
+  {
+    qp++;
+    size--;
+  }
+
+  if(npPrimeM>2)
+    e=(*f)[0]._mp_exp-size;
+  else
+    e=0;
+  res = (number)omAllocBin(rnumber_bin);
+#if defined(LDEBUG)
+  res->debug=123456;
+#endif
+  dest = &(res->z);
+
+  if (e<0)
+  {
+    al = dest->_mp_size = size;
+    if (al<2) al = 2;
+    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
+    for (i=0;i<size;i++) dd[i] = qp[i];
+    bl = 1-e;
+    nn = (mp_ptr)omAlloc(sizeof(mp_limb_t)*bl);
+    nn[bl-1] = 1;
+    for (i=bl-2;i>=0;i--) nn[i] = 0;
+    ndest = &(res->n);
+    ndest->_mp_d = nn;
+    ndest->_mp_alloc = ndest->_mp_size = bl;
+    res->s = 0;
+    in=mpz_mmod_ui(NULL,ndest,npPrimeM);
+    mpz_clear(ndest);
+  }
+  else
+  {
+    al = dest->_mp_size = size+e;
+    if (al<2) al = 2;
+    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
+    for (i=0;i<size;i++) dd[i+e] = qp[i];
+    for (i=0;i<e;i++) dd[i] = 0;
+    res->s = 3;
+  }
+
+  dest->_mp_d = dd;
+  dest->_mp_alloc = al;
+  iz=mpz_mmod_ui(NULL,dest,npPrimeM);
+  mpz_clear(dest);
+  omFreeBin((ADDRESS)res, rnumber_bin);
+  if(res->s==0)
+    iz=(int)npDiv((number)iz,(number)in);
+  return (number)iz;
+}
+
+nMapFunc npSetMap(ring src, ring dst)
+{
+  if (rField_is_Q(src))
+  {
+    return npMap0;
+  }
+  if ( rField_is_Zp(src) )
+  {
+    if (rChar(src) == rChar(dst))
+    {
+      return ndCopy;
+    }
+    else
+    {
+      npMapPrime=rChar(src);
+      return npMapP;
+    }
+  }
+  if (rField_is_long_R(src))
+  {
+    return npMapLongR;
+  }
+  return NULL;      /* default */
+}
+
+// -----------------------------------------------------------
+//  operation for very large primes (32003< p < 2^31-1)
+// ----------------------------------------------------------
+#ifdef NV_OPS
+
+number nvMult (number a,number b)
+{
+  if (((long)a == 0) || ((long)b == 0))
+    return (number)0;
+  else
+    return nvMultM(a,b);
+}
+
+long nvInvMod(long a)
+{
+   long  s, t;
+
+   long  u, v, u0, v0, u1, v1, u2, v2, q, r;
+
+   u1=1; v1=0;
+   u2=0; v2=1;
+   u = a; v = npPrimeM;
+
+   while (v != 0) {
+      q = u / v;
+      r = u % v;
+      u = v;
+      v = r;
+      u0 = u2;
+      v0 = v2;
+      u2 =  u1 - q*u2;
+      v2 = v1- q*v2;
+      u1 = u0;
+      v1 = v0;
+   }
+
+   s = u1;
+   //t = v1;
+   if (s < 0)
+      return s + npPrimeM;
+   else
+      return s;
+}
+
+inline number nvInversM (number c)
+{
+  long inv=nvInvMod((long)c);
+  return (number)inv;
+}
+
+number nvDiv (number a,number b)
+{
+  if ((long)a==0)
+    return (number)0;
+  else if ((long)b==0)
+  {
+    WerrorS("div by 0");
+    return (number)0;
+  }
+  else
+  {
+    number inv=nvInversM(b);
+    return nvMultM(a,inv);
+  }
+}
+number  nvInvers (number c)
+{
+  if ((long)c==0)
+  {
+    WerrorS("1/0");
+    return (number)0;
+  }
+  return nvInversM(c);
+}
+#endif
Index: kernel/modulop.h
===================================================================
--- kernel/modulop.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/modulop.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,176 @@
+#ifndef MODULOP_H
+#define MODULOP_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: modulop.h,v 1.1.1.1 2003-10-06 12:15:58 Singular Exp $ */
+/*
+* ABSTRACT: numbers modulo p (<=32003)
+*/
+#include "structs.h"
+
+// defines are in struct.h
+// define if a*b is with mod instead of tables
+//#define HAVE_MULT_MOD 
+// define if a/b is with mod instead of tables
+//#define HAVE_DIV_MOD 
+// define if an if should be used
+//#define HAVE_GENERIC_ADD
+
+// enable large primes (32003 < p < 2^31-)
+#define NV_OPS
+#define NV_MAX_PRIME 32003
+
+extern long npPrimeM;
+extern int npGen;
+extern long npMapPrime;
+
+BOOLEAN npGreaterZero (number k);
+number  npMult        (number a, number b);
+number  npInit        (int i);
+int     npInt         (number &n);
+number  npAdd         (number a, number b);
+number  npSub         (number a, number b);
+void    npPower       (number a, int i, number * result);
+BOOLEAN npIsZero      (number a);
+BOOLEAN npIsOne       (number a);
+BOOLEAN npIsMOne       (number a);
+number  npDiv         (number a, number b);
+number  npNeg         (number c);
+number  npInvers      (number c);
+BOOLEAN npGreater     (number a, number b);
+BOOLEAN npEqual       (number a, number b);
+void    npWrite       (number &a);
+char *  npRead        (char *s, number *a);
+#ifdef LDEBUG
+BOOLEAN npDBTest      (number a, char *f, int l);
+#endif
+void    npSetChar(int c, ring r);
+void    npInitChar(int c, ring r);
+
+//int     npGetChar();
+
+nMapFunc npSetMap(ring src, ring dst);
+number  npMapP(number from);
+/*-------specials for spolys, do NOT use otherwise--------------------------*/
+/* for npMultM, npSubM, npNegM, npEqualM : */
+#ifdef HAVE_DIV_MOD
+extern CARDINAL *npInvTable;
+#else
+#ifndef HAVE_MULT_MOD
+extern long npPminus1M;
+extern CARDINAL *npExpTable;
+extern CARDINAL *npLogTable;
+#endif
+#endif
+
+#if 0
+inline number npMultM(number a, number b)
+// return (a*b)%n
+{
+   double ab;
+   long q, res;
+
+   ab = ((double) ((int)a)) * ((double) ((int)b));
+   q  = (long) (ab/((double) npPrimeM));  // q could be off by (+/-) 1
+   res = (long) (ab - ((double) q)*((double) npPrimeM));
+   res += (res >> 31) & npPrimeM;
+   res -= npPrimeM;
+   res += (res >> 31) & npPrimeM;
+   return (number)res;
+}
+#endif
+#ifdef HAVE_MULT_MOD
+static inline number npMultM(number a, number b)
+{
+  return (number) 
+    ((((unsigned long) a)*((unsigned long) b)) % ((unsigned long) npPrimeM));
+}
+#else
+static inline number npMultM(number a, number b)
+{
+  int x = npLogTable[(long)a]+npLogTable[(long)b];
+  return (number)npExpTable[x<npPminus1M ? x : x-npPminus1M];
+}
+#endif
+
+#if 0
+inline number npAddAsm(number a, number b, int m)
+{
+  number r;
+    asm ("addl %2, %1; cmpl %3, %1; jb 0f; subl %3, %1; 0:"
+         : "=&r" (r)
+         : "%0" (a), "g" (b), "g" (m)
+         : "cc");
+  return r;
+}
+inline number npSubAsm(number a, number b, int m)
+{
+  number r;
+  asm ("subl %2, %1; jnc 0f; addl %3, %1; 0:"
+        : "=&r" (r)
+        : "%0" (a), "g" (b), "g" (m)
+        : "cc");
+  return r;
+}
+#endif
+#ifdef HAVE_GENERIC_ADD
+static inline number npAddM(number a, number b)
+{
+  long r = (long)a + (long)b;
+  return (number)(r >= npPrimeM ? r - npPrimeM : r);
+}
+static inline number npSubM(number a, number b)
+{
+  return (number)((int)a<(int)b ?
+                       npPrimeM-(int)b+(int)a : (int)a-(int)b);
+}
+#else
+static inline number npAddM(number a, number b)
+{
+   int res = (int)((long)a + (long)b);
+   res -= npPrimeM;
+   res += (res >> 31) & npPrimeM;
+   return (number)res;
+}
+static inline number npSubM(number a, number b)
+{
+   int res = (int)((long)a - (long)b);
+   res += (res >> 31) & npPrimeM;
+   return (number)res;
+}
+#endif
+
+static inline BOOLEAN npIsZeroM (number  a)
+{
+  return 0 == (long)a;
+}
+
+/*
+*inline number npMultM(number a, number b)
+*{
+*  return (number)(((long)a*(long)b) % npPrimeM);
+*}
+*/
+
+#define npNegM(A)      (number)(npPrimeM-(long)(A))
+#define npEqualM(A,B)  ((A)==(B))
+
+
+#ifdef NV_OPS
+static inline number nvMultM(number a, number b)
+{
+#if SIZEOF_LONG == 4
+#define ULONG64 unsigned long long
+#else
+#define ULONG64 unsigned long
+#endif
+  return (number) 
+    ((((ULONG64) a)*((ULONG64) b)) % ((ULONG64) npPrimeM));
+}
+number  nvMult        (number a, number b);
+number  nvDiv         (number a, number b);
+number  nvInvers      (number c);
+#endif
+
+#endif
Index: kernel/mpr_base.cc
===================================================================
--- kernel/mpr_base.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/mpr_base.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,3215 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: mpr_base.cc,v 1.1.1.1 2003-10-06 12:15:56 Singular Exp $ */
+
+/*
+ * ABSTRACT - multipolynomial resultants - resultant matrices
+ *            ( sparse, dense, u-resultant solver )
+ */
+
+#include <math.h>
+
+#include "mod2.h"
+
+#include <mylimits.h>
+#include "omalloc.h"
+
+//-> includes
+#include "structs.h"
+#include "polys.h"
+#include "ideals.h"
+#include "febase.h"
+#include "intvec.h"
+#include "matpol.h"
+#include "numbers.h"
+#ifdef HAVE_FACTORY
+#include "clapsing.h"
+#endif
+#include "sparsmat.h"
+
+#include "mpr_global.h"
+#include "mpr_base.h"
+#include "mpr_numeric.h"
+//<-
+
+extern void nPrint(number n);  // for debugging output
+
+//%s
+//-----------------------------------------------------------------------------
+//-------------- sparse resultant matrix --------------------------------------
+//-----------------------------------------------------------------------------
+
+//-> definitions
+
+//#define mprTEST
+//#define mprMINKSUM
+
+#define MAXPOINTS      10000
+#define MAXINITELEMS   256
+#define LIFT_COOR      50000   // siRand() % LIFT_COOR gives random lift value
+#define SCALEDOWN      100.0  // lift value scale down for linear program
+#define MINVDIST       0.0
+#define RVMULT         0.0001 // multiplicator for random shift vector
+#define MAXRVVAL       50000
+#define MAXVARS        100
+//<-
+
+//-> sparse resultant matrix
+
+/* set of points */
+class pointSet;
+
+
+
+/* sparse resultant matrix class */
+class resMatrixSparse : virtual public resMatrixBase
+{
+public:
+  resMatrixSparse( const ideal _gls, const int special = SNONE );
+  ~resMatrixSparse();
+
+  // public interface according to base class resMatrixBase
+  const ideal getMatrix();
+
+  /** Fills in resMat[][] with evpoint[] and gets determinant
+   * uRPos[i][1]: row of matrix
+   * uRPos[i][idelem+1]: col of u(0)
+   *  uRPos[i][2..idelem]: col of u(1) .. u(n)
+   *  i= 1 .. numSet0
+   */
+  const number getDetAt( const number* evpoint );
+
+  const poly getUDet( const number* evpoint );
+
+private:
+  resMatrixSparse( const resMatrixSparse & );
+
+  void randomVector( const int dim, mprfloat shift[] );
+
+  /** Row Content Function
+   * Finds the largest i such that F[i] is a point, F[i]= a[ij] in A[i] for some j.
+   * Returns -1 iff the point vert does not lie in a cell
+   */
+  int RC( pointSet **pQ, pointSet *E, int vert, mprfloat shift[] );
+
+  /* Remaps a result of LP to the according point set Qi.
+   * Returns false iff remaping was not possible, otherwise true.
+   */
+  bool remapXiToPoint( const int indx, pointSet **pQ, int *set, int *vtx );
+
+  /** create coeff matrix
+   * uRPos[i][1]: row of matrix
+   * uRPos[i][idelem+1]: col of u(0)
+   *  uRPos[i][2..idelem]: col of u(1) .. u(n)
+   *  i= 1 .. numSet0
+   * Returns the dimension of the matrix or -1 in case of an error
+   */
+  int createMatrix( pointSet *E );
+
+  pointSet * minkSumAll( pointSet **pQ, int numq, int dim );
+  pointSet * minkSumTwo( pointSet *Q1, pointSet *Q2, int dim );
+
+private:
+  ideal gls;
+
+  int n, idelem;     // number of variables, polynoms
+  int numSet0;       // number of elements in S0
+  int msize;         // size of matrix
+
+  intvec *uRPos;
+
+  ideal rmat;        // sparse matrix representation
+
+  simplex * LP;      // linear programming stuff
+};
+//<-
+
+//-> typedefs and structs
+poly monomAt( poly p, int i );
+
+typedef unsigned int Coord_t;
+
+struct setID
+{
+  int set;
+  int pnt;
+};
+
+struct onePoint
+{
+  Coord_t * point;             // point[0] is unused, maxial dimension is MAXVARS+1
+  setID rc;                    // filled in by Row Content Function
+  struct onePoint * rcPnt;     // filled in by Row Content Function
+};
+
+typedef struct onePoint * onePointP;
+
+/* sparse matrix entry */
+struct _entry
+{
+  number num;
+  int col;
+  struct _entry * next;
+};
+
+typedef struct _entry * entry;
+//<-
+
+//-> class pointSet
+class pointSet
+{
+private:
+  onePointP *points;     // set of onePoint's, index [1..num], supports of monoms
+  bool lifted;
+
+public:
+  int num;               // number of elements in points
+  int max;               // maximal entries in points, i.e. allocated mem
+  int dim;               // dimension, i.e. valid coord entries in point
+  int index;             // should hold unique identifier of point set
+
+  pointSet( const int _dim, const int _index= 0, const int count= MAXINITELEMS );
+   ~pointSet();
+
+  // pointSet.points[i] equals pointSet[i]
+  inline const onePointP operator[] ( const int index );
+
+  /** Adds a point to pointSet, copy vert[0,...,dim] ot point[num+1][0,...,dim].
+   * Returns false, iff additional memory was allocated ( i.e. num >= max )
+   * else returns true
+   */
+  bool addPoint( const onePointP vert );
+
+  /** Adds a point to pointSet, copy vert[0,...,dim] ot point[num+1][0,...,dim].
+   * Returns false, iff additional memory was allocated ( i.e. num >= max )
+   * else returns true
+   */
+  bool addPoint( const int * vert );
+
+  /** Adds a point to pointSet, copy vert[0,...,dim] ot point[num+1][0,...,dim].
+   * Returns false, iff additional memory was allocated ( i.e. num >= max )
+   * else returns true
+   */
+  bool addPoint( const Coord_t * vert );
+
+  /* Removes the point at intex indx */
+  bool removePoint( const int indx );
+
+  /** Adds point to pointSet, iff pointSet \cap point = \emptyset.
+   * Returns true, iff added, else false.
+   */
+  bool mergeWithExp( const onePointP vert );
+
+  /** Adds point to pointSet, iff pointSet \cap point = \emptyset.
+   * Returns true, iff added, else false.
+   */
+  bool mergeWithExp( const int * vert );
+
+  /* Adds support of poly p to pointSet, iff pointSet \cap point = \emptyset. */
+  void mergeWithPoly( const poly p );
+
+  /* Returns the row polynom multiplicator in vert[] */
+  void getRowMP( const int indx, int * vert );
+
+  /* Returns index of supp(LT(p)) in pointSet. */
+  int getExpPos( const poly p );
+
+  /** sort lex
+   */
+  void sort();
+
+  /** Lifts the point set using sufficiently generic linear lifting
+   * homogeneous forms l[1]..l[dim] in Z. Every l[i] is of the form
+   * L1x1+...+Lnxn, for generic L1..Ln in Z.
+   *
+   * Lifting raises dimension by one!
+   */
+  void lift( int *l= NULL );     // !! increments dim by 1
+  void unlift() { dim--; lifted= false; }
+
+private:
+  pointSet( const pointSet & );
+
+  /** points[a] < points[b] ? */
+  inline bool smaller( int, int );
+
+  /** points[a] > points[b] ? */
+  inline bool larger( int, int );
+
+  /** Checks, if more mem is needed ( i.e. num >= max ),
+   * returns false, if more mem was allocated, else true
+   */
+  inline bool checkMem();
+};
+//<-
+
+//-> class convexHull
+/* Compute convex hull of given exponent set */
+class convexHull
+{
+public:
+  convexHull( simplex * _pLP ) : pLP(_pLP) {}
+  ~convexHull() {}
+
+  /** Computes the point sets of the convex hulls of the supports given
+   * by the polynoms in gls.
+   * Returns Q[].
+   */
+  pointSet ** newtonPolytopesP( const ideal gls );
+  ideal newtonPolytopesI( const ideal gls );
+
+private:
+  /** Returns true iff the support of poly pointPoly is inside the
+   * convex hull of all points given by the  support of poly p.
+   */
+  bool inHull(poly p, poly pointPoly, int m, int site);
+
+private:
+  pointSet **Q;
+  int n;
+  simplex * pLP;
+};
+//<-
+
+//-> class mayanPyramidAlg
+/* Compute all lattice points in a given convex hull */
+class mayanPyramidAlg
+{
+public:
+  mayanPyramidAlg( simplex * _pLP ) : n(pVariables), pLP(_pLP) {}
+  ~mayanPyramidAlg() {}
+
+  /** Drive Mayan Pyramid Algorithm.
+   * The Alg computes conv(Qi[]+shift[]).
+   */
+  pointSet * getInnerPoints( pointSet **_Qi, mprfloat _shift[] );
+
+private:
+
+  /** Recursive Mayan Pyramid algorithm for directly computing MinkowskiSum
+   * lattice points for (n+1)-fold MinkowskiSum of given point sets Qi[].
+   * Recursively for range of dim: dim in [0..n); acoords[0..var) fixed.
+   * Stores only MinkowskiSum points of udist > 0: done by storeMinkowskiSumPoints.
+   */
+  void runMayanPyramid( int dim );
+
+  /**  Compute v-distance via Linear Programing
+   * Linear Program finds the v-distance of the point in accords[].
+   * The v-distance is the distance along the direction v to boundary of
+   * Minkowski Sum of Qi (here vector v is represented by shift[]).
+   * Returns the v-distance or -1.0 if an error occured.
+   */
+  mprfloat vDistance( Coord_t * acoords, int dim );
+
+  /** LP for finding min/max coord in MinkowskiSum, given previous coors.
+   * Assume MinkowskiSum in non-negative quadrants
+   * coor in [0,n); fixed coords in acoords[0..coor)
+   */
+  void mn_mx_MinkowskiSum( int dim, Coord_t *minR, Coord_t *maxR );
+
+  /**  Stores point in E->points[pt], iff v-distance != 0
+   * Returns true iff point was stored, else flase
+   */
+  bool storeMinkowskiSumPoint();
+
+private:
+  pointSet **Qi;
+  pointSet *E;
+  mprfloat *shift;
+
+  int n,idelem;
+
+  Coord_t acoords[MAXVARS+2];
+
+  simplex * pLP;
+};
+//<-
+
+//-> debug output stuff
+#if defined(mprDEBUG_PROT) || defined(mprDEBUG_ALL)
+void print_mat(mprfloat **a, int maxrow, int maxcol)
+{
+  int i, j;
+
+  for (i = 1; i <= maxrow; i++)
+  {
+    PrintS("[");
+    for (j = 1; j <= maxcol; j++) Print("% 7.2f, ", a[i][j]);
+    PrintS("],\n");
+  }
+}
+void print_bmat(mprfloat **a, int nrows, int ncols, int N, int *iposv)
+{
+  int i, j;
+
+  printf("Output matrix from LinProg");
+  for (i = 1; i <= nrows; i++)
+  {
+    printf("\n[ ");
+    if (i == 1) printf("  ");
+    else if (iposv[i-1] <= N) printf("X%d", iposv[i-1]);
+    else printf("Y%d", iposv[i-1]-N+1);
+    for (j = 1; j <= ncols; j++) printf(" %7.2f ",(double)a[i][j]);
+    printf(" ]");
+  } printf("\n");
+  fflush(stdout);
+}
+
+void print_exp( const onePointP vert, int n )
+{
+  int i;
+  for ( i= 1; i <= n; i++ )
+  {
+    Print(" %d",vert->point[i] );
+#ifdef LONG_OUTPUT
+    if ( i < n ) PrintS(", ");
+#endif
+  }
+}
+void print_matrix( matrix omat )
+{
+  int i,j;
+  int val;
+  Print(" matrix m[%d][%d]=(\n",MATROWS( omat ),MATCOLS( omat ));
+  for ( i= 1; i <= MATROWS( omat ); i++ )
+  {
+    for ( j= 1; j <= MATCOLS( omat ); j++ )
+    {
+      if ( (MATELEM( omat, i, j)!=NULL)
+      && (!nIsZero(pGetCoeff( MATELEM( omat, i, j)))))
+      {
+        val= nInt(pGetCoeff( MATELEM( omat, i, j) ));
+        if ( i==MATROWS(omat) && j==MATCOLS(omat) )
+        {
+          Print("%d ",val);
+        }
+        else
+        {
+          Print("%d, ",val);
+        }
+      }
+      else
+      {
+        if ( i==MATROWS(omat) && j==MATCOLS(omat) )
+        {
+          PrintS("  0");
+        }
+        else
+        {
+          PrintS("  0, ");
+        }
+      }
+    }
+    PrintLn();
+  }
+  PrintS(");\n");
+}
+#endif
+//<-
+
+//-> pointSet::*
+pointSet::pointSet( const int _dim, const int _index, const int count )
+  : num(0), max(count), dim(_dim), index(_index)
+{
+  int i;
+  points = (onePointP *)omAlloc( (count+1) * sizeof(onePointP) );
+  for ( i= 0; i <= max; i++ )
+  {
+    points[i]= (onePointP)omAlloc( sizeof(onePoint) );
+    points[i]->point= (Coord_t *)omAlloc0( (dim+2) * sizeof(Coord_t) );
+  }
+  lifted= false;
+}
+
+pointSet::~pointSet()
+{
+  int i;
+  int fdim= lifted ? dim+1 : dim+2;
+  for ( i= 0; i <= max; i++ )
+  {
+    omFreeSize( (ADDRESS) points[i]->point, fdim * sizeof(Coord_t) );
+    omFreeSize( (ADDRESS) points[i], sizeof(onePoint) );
+  }
+  omFreeSize( (ADDRESS) points, (max+1) * sizeof(onePointP) );
+}
+
+inline const onePointP pointSet::operator[] ( const int index )
+{
+  assume( index > 0 && index <= num );
+  return points[index];
+}
+
+inline bool pointSet::checkMem()
+{
+  if ( num >= max )
+  {
+    int i;
+    int fdim= lifted ? dim+1 : dim+2;
+    points= (onePointP*)omReallocSize( points,
+                                 (max+1) * sizeof(onePointP),
+                                 (2*max + 1) * sizeof(onePointP) );
+    for ( i= max+1; i <= max*2; i++ )
+    {
+      points[i]= (onePointP)omAlloc( sizeof(struct onePoint) );
+      points[i]->point= (Coord_t *)omAlloc0( fdim * sizeof(Coord_t) );
+    }
+    max*= 2;
+    mprSTICKYPROT(ST_SPARSE_MEM);
+    return false;
+  }
+  return true;
+}
+
+bool pointSet::addPoint( const onePointP vert )
+{
+  int i;
+  bool ret;
+  num++;
+  ret= checkMem();
+  points[num]->rcPnt= NULL;
+  for ( i= 1; i <= dim; i++ ) points[num]->point[i]= vert->point[i];
+  return ret;
+}
+
+bool pointSet::addPoint( const int * vert )
+{
+  int i;
+  bool ret;
+  num++;
+  ret= checkMem();
+  points[num]->rcPnt= NULL;
+  for ( i= 1; i <= dim; i++ ) points[num]->point[i]= (Coord_t) vert[i];
+  return ret;
+}
+
+bool pointSet::addPoint( const Coord_t * vert )
+{
+  int i;
+  bool ret;
+  num++;
+  ret= checkMem();
+  points[num]->rcPnt= NULL;
+  for ( i= 0; i < dim; i++ ) points[num]->point[i+1]= vert[i];
+  return ret;
+}
+
+bool pointSet::removePoint( const int indx )
+{
+  assume( indx > 0 && indx <= num );
+  if ( indx != num )
+  {
+    onePointP tmp;
+    tmp= points[indx];
+    points[indx]= points[num];
+    points[num]= tmp;
+  }
+  num--;
+
+  return true;
+}
+
+bool pointSet::mergeWithExp( const onePointP vert )
+{
+  int i,j;
+
+  for ( i= 1; i <= num; i++ )
+  {
+    for ( j= 1; j <= dim; j++ )
+      if ( points[i]->point[j] != vert->point[j] ) break;
+    if ( j > dim ) break;
+  }
+
+  if ( i > num )
+  {
+    addPoint( vert );
+    return true;
+  }
+  return false;
+}
+
+bool pointSet::mergeWithExp( const int * vert )
+{
+  int i,j;
+
+  for ( i= 1; i <= num; i++ )
+  {
+    for ( j= 1; j <= dim; j++ )
+      if ( points[i]->point[j] != (Coord_t) vert[j] ) break;
+    if ( j > dim ) break;
+  }
+
+  if ( i > num )
+  {
+    addPoint( vert );
+    return true;
+  }
+  return false;
+}
+
+void pointSet::mergeWithPoly( const poly p )
+{
+  int i,j;
+  poly piter= p;
+  int * vert;
+  vert= (int *)omAlloc( (dim+1) * sizeof(int) );
+
+  while ( piter )
+  {
+    pGetExpV( piter, vert );
+
+    for ( i= 1; i <= num; i++ )
+    {
+      for ( j= 1; j <= dim; j++ )
+        if ( points[i]->point[j] != (Coord_t) vert[j] ) break;
+      if ( j > dim ) break;
+    }
+
+    if ( i > num )
+    {
+      addPoint( vert );
+    }
+
+    pIter( piter );
+  }
+  omFreeSize( (ADDRESS) vert, (dim+1) * sizeof(int) );
+}
+
+int pointSet::getExpPos( const poly p )
+{
+  int * vert;
+  int i,j;
+
+  // hier unschoen...
+  vert= (int *)omAlloc( (dim+1) * sizeof(int) );
+
+  pGetExpV( p, vert );
+  for ( i= 1; i <= num; i++ )
+  {
+    for ( j= 1; j <= dim; j++ )
+      if ( points[i]->point[j] != (Coord_t) vert[j] ) break;
+    if ( j > dim ) break;
+  }
+  omFreeSize( (ADDRESS) vert, (dim+1) * sizeof(int) );
+
+  if ( i > num ) return 0;
+  else return i;
+}
+
+void pointSet::getRowMP( const int indx, int * vert )
+{
+  assume( indx > 0 && indx <= num && points[indx]->rcPnt );
+  int i;
+
+  vert[0]= 0;
+  for ( i= 1; i <= dim; i++ )
+    vert[i]= (int)(points[indx]->point[i] - points[indx]->rcPnt->point[i]);
+}
+
+inline bool pointSet::smaller( int a, int b )
+{
+  int i;
+
+  for ( i= 1; i <= dim; i++ )
+  {
+    if ( points[a]->point[i] > points[b]->point[i] )
+    {
+      return false;
+    }
+    if ( points[a]->point[i] < points[b]->point[i] )
+    {
+      return true;
+    }
+  }
+
+ return false; // they are equal
+}
+
+inline bool pointSet::larger( int a, int b )
+{
+  int i;
+
+  for ( i= 1; i <= dim; i++ )
+  {
+    if ( points[a]->point[i] < points[b]->point[i] )
+    {
+      return false;
+    }
+    if ( points[a]->point[i] > points[b]->point[i] )
+    {
+      return true;
+    }
+  }
+
+ return false; // they are equal
+}
+
+void pointSet::sort()
+{
+  int i,j;
+  bool found= true;
+  onePointP tmp;
+
+  while ( found )
+  {
+    found= false;
+    for ( i= 1; i < num; i++ )
+    {
+      if ( larger( i, i+1 ) )
+      {
+        tmp= points[i];
+        points[i]= points[i+1];
+        points[i+1]= tmp;
+
+        found= true;
+      }
+    }
+  }
+}
+
+void pointSet::lift( int l[] )
+{
+  bool outerL= true;
+  int i, j;
+  int sum;
+
+  dim++;
+
+  if ( l==NULL )
+  {
+    outerL= false;
+    l= (int *)omAlloc( (dim+1) * sizeof(int) ); // [1..dim-1]
+
+    for(i = 1; i < dim; i++)
+    {
+      l[i]= 1 + siRand() % LIFT_COOR;
+    }
+  }
+  for ( j=1; j <= num; j++ )
+  {
+    sum= 0;
+    for ( i=1; i < dim; i++ )
+    {
+      sum += (int)points[j]->point[i] * l[i];
+    }
+    points[j]->point[dim]= sum;
+  }
+
+#ifdef mprDEBUG_ALL
+  PrintS(" lift vector: ");
+  for ( j=1; j < dim; j++ ) Print(" %d ",l[j] );
+  PrintLn();
+#ifdef mprDEBUG_ALL
+  PrintS(" lifted points: \n");
+  for ( j=1; j <= num; j++ )
+  {
+    Print("%d: <",j);print_exp(points[j],dim);PrintS(">\n");
+  }
+  PrintLn();
+#endif
+#endif
+
+  lifted= true;
+
+  if ( !outerL ) omFreeSize( (ADDRESS) l, (dim+1) * sizeof(int) );
+}
+//<-
+
+//-> global functions
+// Returns the monom at pos i in poly p
+poly monomAt( poly p, int i )
+{
+  assume( i > 0 );
+  poly iter= p;
+  for ( int j= 1; (j < i) && iter; j++ ) iter= pIter(iter);
+  return iter;
+}
+//<-
+
+//-> convexHull::*
+bool convexHull::inHull(poly p, poly pointPoly, int m, int site)
+{
+  int i, j, col;
+
+  pLP->m = n+1;
+  pLP->n = m;                // this includes col of cts
+
+  pLP->LiPM[1][1] = +0.0;
+  pLP->LiPM[1][2] = +1.0;        // optimize (arbitrary) var
+  pLP->LiPM[2][1] = +1.0;
+  pLP->LiPM[2][2] = -1.0;         // lambda vars sum up to 1
+
+  for ( j=3; j <= pLP->n; j++)
+  {
+    pLP->LiPM[1][j] = +0.0;
+    pLP->LiPM[2][j] = -1.0;
+  }
+
+  for( i= 1; i <= n; i++) {        // each row constraints one coor
+    pLP->LiPM[i+2][1] = (mprfloat)pGetExp(pointPoly,i);
+    col = 2;
+    for( j= 1; j <= m; j++ )
+    {
+      if( j != site )
+      {
+        pLP->LiPM[i+2][col] = -(mprfloat)pGetExp( monomAt(p,j), i );
+        col++;
+      }
+    }
+  }
+
+#ifdef mprDEBUG_ALL
+  PrintS("Matrix of Linear Programming\n");
+  print_mat( pLP->LiPM, pLP->m+1,pLP->n);
+#endif
+
+  pLP->m3= pLP->m;
+
+  pLP->compute();
+
+  return (pLP->icase == 0);
+}
+
+// mprSTICKYPROT:
+// ST_SPARSE_VADD: new vertex of convex hull added
+// ST_SPARSE_VREJ: point rejected (-> inside hull)
+pointSet ** convexHull::newtonPolytopesP( const ideal gls )
+{
+  int i, j, k;
+  int m;  // Anzahl der Exponentvektoren im i-ten Polynom (gls->m)[i] des Ideals gls
+  int idelem= IDELEMS(gls);
+  int * vert;
+
+  n= pVariables;
+  vert= (int *)omAlloc( (idelem+1) * sizeof(int) );
+
+  Q = (pointSet **)omAlloc( idelem * sizeof(pointSet*) );        // support hulls
+  for ( i= 0; i < idelem; i++ )
+    Q[i] = new pointSet( pVariables, i+1, pLength((gls->m)[i])+1 );
+
+  for( i= 0; i < idelem; i++ )
+  {
+    k=1;
+    m = pLength( (gls->m)[i] );
+
+    poly p= (gls->m)[i];
+    for( j= 1; j <= m; j++) {  // für jeden Exponentvektor
+      if( !inHull( (gls->m)[i], p, m, j ) )
+      {
+        pGetExpV( p, vert );
+        Q[i]->addPoint( vert );
+        k++;
+        mprSTICKYPROT(ST_SPARSE_VADD);
+      }
+      else
+      {
+        mprSTICKYPROT(ST_SPARSE_VREJ);
+      }
+      pIter( p );
+    } // j
+    mprSTICKYPROT("\n");
+  } // i
+
+  omFreeSize( (ADDRESS) vert, (idelem+1) * sizeof(int) );
+
+#ifdef mprDEBUG_PROT
+  PrintLn();
+  for( i= 0; i < idelem; i++ )
+  {
+    Print(" \\Conv(Qi[%d]): #%d\n", i,Q[i]->num );
+    for ( j=1; j <= Q[i]->num; j++ )
+    {
+      Print("%d: <",j);print_exp( (*Q[i])[j] , pVariables );PrintS(">\n");
+    }
+    PrintLn();
+  }
+#endif
+
+  return Q;
+}
+
+// mprSTICKYPROT:
+// ST_SPARSE_VADD: new vertex of convex hull added
+// ST_SPARSE_VREJ: point rejected (-> inside hull)
+ideal convexHull::newtonPolytopesI( const ideal gls )
+{
+  int i, j;
+  int m;  // Anzahl der Exponentvektoren im i-ten Polynom (gls->m)[i] des Ideals gls
+  int idelem= IDELEMS(gls);
+  ideal id;
+  poly p,pid,pd;
+  int * vert;
+
+  n= pVariables;
+  vert= (int *)omAlloc( (idelem+1) * sizeof(int) );
+  id= idInit( idelem, 1 );
+
+  for( i= 0; i < idelem; i++ )
+  {
+    m = pLength( (gls->m)[i] );
+
+    p= (gls->m)[i];
+    for( j= 1; j <= m; j++) {  // für jeden Exponentvektor
+      if( !inHull( (gls->m)[i], p, m, j ) )
+      {
+        if ( (id->m)[i] == NULL )
+        {
+          (id->m)[i]= pHead(p);
+          pid=(id->m)[i];
+        }
+        else
+        {
+          pNext(pid)= pHead(p);
+          pIter(pid);
+          pNext(pid)= NULL;
+        }
+        mprSTICKYPROT(ST_SPARSE_VADD);
+      }
+      else
+      {
+        mprSTICKYPROT(ST_SPARSE_VREJ);
+      }
+      pIter( p );
+    } // j
+    mprSTICKYPROT("\n");
+  } // i
+
+  omFreeSize( (ADDRESS) vert, (idelem+1) * sizeof(int) );
+
+#ifdef mprDEBUG_PROT
+  PrintLn();
+  for( i= 0; i < idelem; i++ )
+  {
+  }
+#endif
+
+  return id;
+}
+//<-
+
+//-> mayanPyramidAlg::*
+pointSet * mayanPyramidAlg::getInnerPoints( pointSet **_Qi, mprfloat _shift[] )
+{
+  int i;
+
+  Qi= _Qi;
+  shift= _shift;
+
+  E= new pointSet( Qi[0]->dim ); // E has same dim as Qi[...]
+
+  for ( i= 0; i < MAXVARS+2; i++ ) acoords[i]= 0;
+
+  runMayanPyramid(0);
+
+  mprSTICKYPROT("\n");
+
+  return E;
+}
+
+mprfloat mayanPyramidAlg::vDistance( Coord_t * acoords, int dim )
+{
+  int i, ii, j, k, col, r;
+  int numverts, cols;
+
+  numverts = 0;
+  for( i=0; i<=n; i++)
+  {
+    numverts += Qi[i]->num;
+  }
+  cols = numverts + 2;
+
+  //if( dim < 1 || dim > n )
+  //  WerrorS("mayanPyramidAlg::vDistance: Known coords dim off range");
+
+  pLP->LiPM[1][1] = 0.0;
+  pLP->LiPM[1][2] = 1.0;        // maximize
+  for( j=3; j<=cols; j++) pLP->LiPM[1][j] = 0.0;
+
+  for( i=0; i <= n; i++ )
+  {
+    pLP->LiPM[i+2][1] = 1.0;
+    pLP->LiPM[i+2][2] = 0.0;
+  }
+  for( i=1; i<=dim; i++)
+  {
+    pLP->LiPM[n+2+i][1] = (mprfloat)(acoords[i-1]);
+    pLP->LiPM[n+2+i][2] = -shift[i];
+  }
+
+  ii = -1;
+  col = 2;
+  for ( i= 0; i <= n; i++ )
+  {
+    ii++;
+    for( k= 1; k <= Qi[ii]->num; k++ )
+    {
+      col++;
+      for ( r= 0; r <= n; r++ )
+      {
+        if ( r == i ) pLP->LiPM[r+2][col] = -1.0;
+        else pLP->LiPM[r+2][col] = 0.0;
+      }
+      for( r= 1; r <= dim; r++ )
+        pLP->LiPM[r+n+2][col] = -(mprfloat)((*Qi[ii])[k]->point[r]);
+    }
+  }
+
+  if( col != cols)
+    Werror("mayanPyramidAlg::vDistance:"
+           "setting up matrix for udist: col %d != cols %d",col,cols);
+
+  pLP->m = n+dim+1;
+  pLP->m3= pLP->m;
+  pLP->n=cols-1;
+
+#ifdef mprDEBUG_ALL
+  Print("vDistance LP, known koords dim=%d, constr %d, cols %d, acoords= ",
+        dim,pLP->m,cols);
+  for( i= 0; i < dim; i++ )
+    Print(" %d",acoords[i]);
+  PrintLn();
+  print_mat( pLP->LiPM, pLP->m+1, cols);
+#endif
+
+  pLP->compute();
+
+#ifdef mprDEBUG_ALL
+  PrintS("LP returns matrix\n");
+  print_bmat( pLP->LiPM, pLP->m+1, cols+1-pLP->m, cols, pLP->iposv);
+#endif
+
+  if( pLP->icase != 0 )
+  {  // check for errors
+    WerrorS("mayanPyramidAlg::vDistance:");
+    if( pLP->icase == 1 )
+      WerrorS(" Unbounded v-distance: probably 1st v-coor=0");
+    else if( pLP->icase == -1 )
+      WerrorS(" Infeasible v-distance");
+    else
+      WerrorS(" Unknown error");
+    return -1.0;
+  }
+
+  return pLP->LiPM[1][1];
+}
+
+void  mayanPyramidAlg::mn_mx_MinkowskiSum( int dim, Coord_t *minR, Coord_t *maxR )
+{
+  int i, j, k, cols, cons;
+  int la_cons_row;
+
+  cons = n+dim+2;
+
+  // first, compute minimum
+  //
+
+  // common part of the matrix
+  pLP->LiPM[1][1] = 0.0;
+  for( i=2; i<=n+2; i++)
+  {
+    pLP->LiPM[i][1] = 1.0;        // 1st col
+    pLP->LiPM[i][2] = 0.0;        // 2nd col
+  }
+
+  la_cons_row = 1;
+  cols = 2;
+  for( i=0; i<=n; i++)
+  {
+    la_cons_row++;
+    for( j=1; j<= Qi[i]->num; j++)
+    {
+      cols++;
+      pLP->LiPM[1][cols] = 0.0;        // set 1st row 0
+      for( k=2; k<=n+2; k++)
+      {  // lambdas sum up to 1
+        if( k != la_cons_row) pLP->LiPM[k][cols] = 0.0;
+        else pLP->LiPM[k][cols] = -1.0;
+      }
+      for( k=1; k<=n; k++)
+        pLP->LiPM[k+n+2][cols] = -(mprfloat)((*Qi[i])[j]->point[k]);
+    } // j
+  } // i
+
+  for( i= 0; i < dim; i++ )
+  {                // fixed coords
+    pLP->LiPM[i+n+3][1] = acoords[i];
+    pLP->LiPM[i+n+3][2] = 0.0;
+  }
+  pLP->LiPM[dim+n+3][1] = 0.0;
+
+
+  pLP->LiPM[1][2] = -1.0;                        // minimize
+  pLP->LiPM[dim+n+3][2] = 1.0;
+
+#ifdef mprDEBUG_ALL
+  Print("\nThats the matrix for minR, dim= %d, acoords= ",dim);
+  for( i= 0; i < dim; i++ )
+    Print(" %d",acoords[i]);
+  PrintLn();
+  print_mat( pLP->LiPM, cons+1, cols);
+#endif
+
+  // simplx finds MIN for obj.fnc, puts it in [1,1]
+  pLP->m= cons;
+  pLP->n= cols-1;
+  pLP->m3= cons;
+
+  pLP->compute();
+
+  if ( pLP->icase != 0 )
+  { // check for errors
+    if( pLP->icase < 0)
+      WerrorS(" mn_mx_MinkowskiSum: LinearProgram: minR: infeasible");
+    else if( pLP->icase > 0)
+      WerrorS(" mn_mx_MinkowskiSum: LinearProgram: minR: unbounded");
+  }
+
+  *minR = (Coord_t)( -pLP->LiPM[1][1] + 1.0 - SIMPLEX_EPS );
+
+  // now compute maximum
+  //
+
+  // common part of the matrix again
+  pLP->LiPM[1][1] = 0.0;
+  for( i=2; i<=n+2; i++)
+  {
+    pLP->LiPM[i][1] = 1.0;
+    pLP->LiPM[i][2] = 0.0;
+  }
+  la_cons_row = 1;
+  cols = 2;
+  for( i=0; i<=n; i++)
+  {
+    la_cons_row++;
+    for( j=1; j<=Qi[i]->num; j++)
+    {
+      cols++;
+      pLP->LiPM[1][cols] = 0.0;
+      for( k=2; k<=n+2; k++)
+      {
+        if( k != la_cons_row) pLP->LiPM[k][cols] = 0.0;
+        else pLP->LiPM[k][cols] = -1.0;
+      }
+      for( k=1; k<=n; k++)
+        pLP->LiPM[k+n+2][cols] = -(mprfloat)((*Qi[i])[j]->point[k]);
+    } // j
+  }  // i
+
+  for( i= 0; i < dim; i++ )
+  {                // fixed coords
+    pLP->LiPM[i+n+3][1] = acoords[i];
+    pLP->LiPM[i+n+3][2] = 0.0;
+  }
+  pLP->LiPM[dim+n+3][1] = 0.0;
+
+  pLP->LiPM[1][2] = 1.0;                      // maximize
+  pLP->LiPM[dim+n+3][2] = 1.0;                // var = sum of pnt coords
+
+#ifdef mprDEBUG_ALL
+  Print("\nThats the matrix for maxR, dim= %d\n",dim);
+  print_mat( pLP->LiPM, cons+1, cols);
+#endif
+
+  pLP->m= cons;
+  pLP->n= cols-1;
+  pLP->m3= cons;
+
+  // simplx finds MAX for obj.fnc, puts it in [1,1]
+  pLP->compute();
+
+  if ( pLP->icase != 0 )
+  {
+    if( pLP->icase < 0)
+      WerrorS(" mn_mx_MinkowskiSum: LinearProgram: maxR: infeasible");
+    else if( pLP->icase > 0)
+      WerrorS(" mn_mx_MinkowskiSum: LinearProgram: maxR: unbounded");
+  }
+
+  *maxR = (Coord_t)( pLP->LiPM[1][1] + SIMPLEX_EPS );
+
+#ifdef mprDEBUG_ALL
+  Print("  Range for dim=%d: [%d,%d]\n", dim, *minR, *maxR);
+#endif
+}
+
+// mprSTICKYPROT:
+// ST_SPARSE_VREJ: rejected point
+// ST_SPARSE_VADD: added point to set
+bool mayanPyramidAlg::storeMinkowskiSumPoint()
+{
+  mprfloat dist;
+
+  // determine v-distance of point pt
+  dist= vDistance( &(acoords[0]), n );
+
+  // store only points with v-distance > minVdist
+  if( dist <= MINVDIST + SIMPLEX_EPS )
+  {
+    mprSTICKYPROT(ST_SPARSE_VREJ);
+    return false;
+  }
+
+  E->addPoint( &(acoords[0]) );
+  mprSTICKYPROT(ST_SPARSE_VADD);
+
+  return true;
+}
+
+// mprSTICKYPROT:
+// ST_SPARSE_MREC1: recurse
+// ST_SPARSE_MREC2: recurse with extra points
+// ST_SPARSE_MPEND: end
+void mayanPyramidAlg::runMayanPyramid( int dim )
+{
+  Coord_t minR, maxR;
+  mprfloat dist;
+
+  // step 3
+  mn_mx_MinkowskiSum( dim, &minR, &maxR );
+
+#ifdef mprDEBUG_ALL
+  int i;
+  for( i=0; i <= dim; i++) Print("acoords[%d]=%d ",i,(int)acoords[i]);
+  Print(":: [%d,%d]\n", minR, maxR);
+#endif
+
+  // step 5 -> terminate
+  if( dim == n-1 )
+  {
+    int lastKilled = 0;
+    // insert points
+    acoords[dim] = minR;
+    while( acoords[dim] <= maxR )
+    {
+      if( !storeMinkowskiSumPoint() )
+        lastKilled++;
+      acoords[dim]++;
+    }
+    mprSTICKYPROT(ST_SPARSE_MPEND);
+    return;
+  }
+
+  // step 4 -> recurse at step 3
+  acoords[dim] = minR;
+  while ( acoords[dim] <= maxR )
+  {
+    if ( (acoords[dim] > minR) && (acoords[dim] <= maxR) )
+    {     // acoords[dim] >= minR  ??
+      mprSTICKYPROT(ST_SPARSE_MREC1);
+      runMayanPyramid( dim + 1 );         // recurse with higer dimension
+    }
+    else
+    {
+      // get v-distance of pt
+      dist= vDistance( &(acoords[0]), dim + 1 );// dim+1 == known coordinates
+
+      if( dist >= SIMPLEX_EPS )
+      {
+        mprSTICKYPROT(ST_SPARSE_MREC2);
+        runMayanPyramid( dim + 1 );       // recurse with higer dimension
+      }
+    }
+    acoords[dim]++;
+  } // while
+}
+//<-
+
+//-> resMatrixSparse::*
+bool resMatrixSparse::remapXiToPoint( const int indx, pointSet **pQ, int *set, int *pnt )
+{
+  int i,n= pVariables;
+  int loffset= 0;
+  for ( i= 0; i <= n; i++ )
+  {
+    if ( (loffset < indx) && (indx <= pQ[i]->num + loffset) )
+    {
+      *set= i;
+      *pnt= indx-loffset;
+      return true;
+    }
+    else loffset+= pQ[i]->num;
+  }
+  return false;
+}
+
+// mprSTICKYPROT
+// ST_SPARSE_RC: point added
+int resMatrixSparse::RC( pointSet **pQ, pointSet *E, int vert, mprfloat shift[] )
+{
+  int i, j, k,c ;
+  int size;
+  bool found= true;
+  mprfloat cd;
+  int set,pnt,onum;
+  int bucket[MAXVARS+2];
+  setID *optSum;
+
+  LP->n = 1;
+  LP->m = n + n + 1;   // number of constrains
+
+  // fill in LP matrix
+  for ( i= 0; i <= n; i++ )
+  {
+    size= pQ[i]->num;
+    for ( k= 1; k <= size; k++ )
+    {
+      LP->n++;
+
+      // objective funtion, minimize
+      LP->LiPM[1][LP->n] = - ( (mprfloat) (*pQ[i])[k]->point[pQ[i]->dim] / SCALEDOWN );
+
+      // lambdas sum up to 1
+      for ( j = 0; j <= n; j++ )
+      {
+        if ( i==j )
+          LP->LiPM[j+2][LP->n] = -1.0;
+        else
+          LP->LiPM[j+2][LP->n] = 0.0;
+      }
+
+      // the points
+      for ( j = 1; j <= n; j++ )
+      {
+        LP->LiPM[j+n+2][LP->n] =  - ( (mprfloat) (*pQ[i])[k]->point[j] );
+      }
+    }
+  }
+
+  for ( j = 0; j <= n; j++ ) LP->LiPM[j+2][1] = 1.0;
+  for ( j= 1; j <= n; j++ )
+  {
+    LP->LiPM[j+n+2][1]= (mprfloat)(*E)[vert]->point[j] - shift[j];
+  }
+  LP->n--;
+
+  LP->LiPM[1][1] = 0.0;
+
+#ifdef mprDEBUG_ALL
+  PrintLn();
+  Print(" n= %d, LP->m=M= %d, LP->n=N= %d\n",n,LP->m,LP->n);
+  print_mat(LP->LiPM, LP->m+1, LP->n+1);
+#endif
+
+  LP->m3= LP->m;
+
+  LP->compute();
+
+  if ( LP->icase < 0 )
+  {
+    // infeasibility: the point does not lie in a cell -> remove it
+    return -1;
+  }
+
+  // store result
+  (*E)[vert]->point[E->dim]= (int)(-LP->LiPM[1][1] * SCALEDOWN);
+
+#ifdef mprDEBUG_ALL
+  Print(" simplx returned %d, Objective value = %f\n", LP->icase, LP->LiPM[1][1]);
+  //print_bmat(LP->LiPM, NumCons + 1, LP->n+1-NumCons, LP->n+1, LP->iposv); // ( rows= M+1, cols= N+1-m3 )
+  //print_mat(LP->LiPM, NumCons+1, LP->n);
+#endif
+
+#if 1
+  // sort LP results
+  while (found)
+  {
+    found=false;
+    for ( i= 1; i < LP->m; i++ )
+    {
+      if ( LP->iposv[i] > LP->iposv[i+1] )
+      {
+
+        c= LP->iposv[i];
+        LP->iposv[i]=LP->iposv[i+1];
+        LP->iposv[i+1]=c;
+
+        cd=LP->LiPM[i+1][1];
+        LP->LiPM[i+1][1]=LP->LiPM[i+2][1];
+        LP->LiPM[i+2][1]=cd;
+
+        found= true;
+      }
+    }
+  }
+#endif
+
+#ifdef mprDEBUG_ALL
+  print_bmat(LP->LiPM, LP->m + 1, LP->n+1-LP->m, LP->n+1, LP->iposv);
+  PrintS(" now split into sets\n");
+#endif
+
+
+  // init bucket
+  for ( i= 0; i <= E->dim; i++ ) bucket[i]= 0;
+  // remap results of LP to sets Qi
+  c=0;
+  optSum= (setID*)omAlloc( (LP->m) * sizeof(struct setID) );
+  for ( i= 0; i < LP->m; i++ )
+  {
+    //Print("% .15f\n",LP->LiPM[i+2][1]);
+    if ( LP->LiPM[i+2][1] > 1e-12 )
+    {
+      if ( !remapXiToPoint( LP->iposv[i+1], pQ, &(optSum[c].set), &(optSum[c].pnt) ) )
+      {
+        Werror(" resMatrixSparse::RC: Found bad solution in LP: %d!",LP->iposv[i+1]);
+        WerrorS(" resMatrixSparse::RC: remapXiToPoint faild!");
+        return -1;
+      }
+      bucket[optSum[c].set]++;
+      c++;
+    }
+  }
+
+  onum= c;
+  // find last min in bucket[]: maximum i such that Fi is a point
+  c= 0;
+  for ( i= 1; i < E->dim; i++ )
+  {
+    if ( bucket[c] >= bucket[i] )
+    {
+      c= i;
+    }
+  }
+  // find matching point set
+  for ( i= onum - 1; i >= 0; i-- )
+  {
+    if ( optSum[i].set == c )
+      break;
+  }
+  // store
+  (*E)[vert]->rc.set= c;
+  (*E)[vert]->rc.pnt= optSum[i].pnt;
+  (*E)[vert]->rcPnt= (*pQ[c])[optSum[i].pnt];
+  // count
+  if ( (*E)[vert]->rc.set == linPolyS ) numSet0++;
+
+#ifdef mprDEBUG_PROT
+  Print("\n Point E[%d] was <",vert);print_exp((*E)[vert],E->dim-1);Print(">, bucket={");
+  for ( j= 0; j < E->dim; j++ )
+  {
+    Print(" %d",bucket[j]);
+  }
+  PrintS(" }\n optimal Sum: Qi ");
+  for ( j= 0; j < LP->m; j++ )
+  {
+    Print(" [ %d, %d ]",optSum[j].set,optSum[j].pnt);
+  }
+  Print(" -> i= %d, j = %d\n",(*E)[vert]->rc.set,optSum[i].pnt);
+#endif
+
+  // clean up
+  omFreeSize( (ADDRESS) optSum, (LP->m) * sizeof(struct setID) );
+
+  mprSTICKYPROT(ST_SPARSE_RC);
+
+  return (int)(-LP->LiPM[1][1] * SCALEDOWN);
+}
+
+// create coeff matrix
+int resMatrixSparse::createMatrix( pointSet *E )
+{
+  // sparse matrix
+  //    uRPos[i][1]: row of matrix
+  //    uRPos[i][idelem+1]: col of u(0)
+  //    uRPos[i][2..idelem]: col of u(1) .. u(n)
+  //    i= 1 .. numSet0
+  int i,j,epos;
+  int rp,cp;
+  poly rowp,epp;
+  poly iterp;
+  int *epp_mon, *eexp;
+
+  epp_mon= (int *)omAlloc( (n+2) * sizeof(int) );
+  eexp= (int *)omAlloc0((pVariables+1)*sizeof(int));
+
+  totDeg= numSet0;
+
+  mprSTICKYPROT2(" size of matrix: %d\n", E->num);
+  mprSTICKYPROT2("  resultant deg: %d\n", numSet0);
+
+  uRPos= new intvec( numSet0, pLength((gls->m)[0])+1, 0 );
+
+  // sparse Matrix represented as a module where
+  // each poly is column vector ( pSetComp(p,k) gives the row )
+  rmat= idInit( E->num, E->num );    // cols, rank= number of rows
+  msize= E->num;
+
+  rp= 1;
+  rowp= NULL;
+  epp= pOne();
+  for ( i= 1; i <= E->num; i++ )
+  {       // for every row
+    E->getRowMP( i, epp_mon );           // compute (p-a[ij]), (i,j) = RC(p)
+    pSetExpV( epp, epp_mon );
+
+    //
+    rowp= ppMult_qq( epp, (gls->m)[(*E)[i]->rc.set] );  // x^(p-a[ij]) * f(i)
+
+    cp= 2;
+    // get column for every monomial in rowp and store it
+    iterp= rowp;
+    while ( iterp!=NULL )
+    {
+      epos= E->getExpPos( iterp );
+      if ( epos == 0 )
+      {
+        // this can happen, if the shift vektor or the lift funktions
+        // are not generically choosen.
+        Werror("resMatrixSparse::createMatrix: Found exponent not in E, id %d, set [%d, %d]!",
+               i,(*E)[i]->rc.set,(*E)[i]->rc.pnt);
+        return i;
+      }
+      pSetExpV(iterp,eexp);
+      pSetComp(iterp, epos );
+      pSetm(iterp);
+      if ( (*E)[i]->rc.set == linPolyS )
+      { // store coeff positions
+        IMATELEM(*uRPos,rp,cp)= epos;
+        cp++;
+      }
+      pIter( iterp );
+    } // while
+    if ( (*E)[i]->rc.set == linPolyS )
+    {   // store row
+      IMATELEM(*uRPos,rp,1)= i-1;
+      rp++;
+    }
+    (rmat->m)[i-1]= rowp;
+  } // for
+
+  pDelete( &epp );
+  omFreeSize( (ADDRESS) epp_mon, (n+2) * sizeof(int) );
+  omFreeSize( (ADDRESS) eexp, (pVariables+1)*sizeof(int));
+
+#ifdef mprDEBUG_ALL
+  if ( E->num <= 40 )
+  {
+    matrix mout= idModule2Matrix( idCopy(rmat) );
+    print_matrix(mout);
+  }
+  for ( i= 1; i <= numSet0; i++ )
+  {
+    Print(" row  %d contains coeffs of f_%d\n",IMATELEM(*uRPos,i,1),linPolyS);
+  }
+  PrintS(" Sparse Matrix done\n");
+#endif
+
+  return E->num;
+}
+
+// find a sufficiently generic and small vector
+void resMatrixSparse::randomVector( const int dim, mprfloat shift[] )
+{
+  int i,j;
+  i= 1;
+  time_t *tp = NULL;
+
+  while ( i <= dim )
+  {
+    shift[i]= (mprfloat) (RVMULT*(siRand()%MAXRVVAL)/(mprfloat)MAXRVVAL);
+    i++;
+    for ( j= 1; j < i-1; j++ )
+    {
+      if ( (shift[j] < shift[i-1] + SIMPLEX_EPS) && (shift[j] > shift[i-1] - SIMPLEX_EPS) )
+      {
+        i--;
+        break;
+      }
+    }
+  }
+}
+
+pointSet * resMatrixSparse::minkSumTwo( pointSet *Q1, pointSet *Q2, int dim )
+{
+  pointSet *vs;
+  onePoint vert;
+  int j,k,l;
+
+  vert.point=(Coord_t*)omAlloc( (pVariables+2) * sizeof(Coord_t) );
+
+  vs= new pointSet( dim );
+
+  for ( j= 1; j <= Q1->num; j++ )
+  {
+    for ( k= 1; k <= Q2->num; k++ )
+    {
+      for ( l= 1; l <= dim; l++ )
+      {
+        vert.point[l]= (*Q1)[j]->point[l] + (*Q2)[k]->point[l];
+      }
+      vs->mergeWithExp( &vert );
+      //vs->addPoint( &vert );
+    }
+  }
+
+  omFreeSize( (ADDRESS) vert.point, (pVariables+2) * sizeof(Coord_t) );
+
+  return vs;
+}
+
+pointSet * resMatrixSparse::minkSumAll( pointSet **pQ, int numq, int dim )
+{
+  pointSet *vs,*vs_old;
+  int j;
+
+  vs= new pointSet( dim );
+
+  for ( j= 1; j <= pQ[0]->num; j++ ) vs->addPoint( (*pQ[0])[j] );
+
+  for ( j= 1; j < numq; j++ )
+  {
+    vs_old= vs;
+    vs= minkSumTwo( vs_old, pQ[j], dim );
+
+    delete vs_old;
+  }
+
+  return vs;
+}
+
+//----------------------------------------------------------------------------------------
+
+resMatrixSparse::resMatrixSparse( const ideal _gls, const int special )
+  : resMatrixBase(), gls( _gls )
+{
+  pointSet **Qi; // vertices sets of Conv(Supp(f_i)), i=0..idelem
+  pointSet *E;   // all integer lattice points of the minkowski sum of Q0...Qn
+  int i,j,k;
+  int pnt;
+  int totverts;                // total number of exponent vectors in ideal gls
+  mprfloat shift[MAXVARS+2];   // shiftvector delta, index [1..dim]
+
+  if ( pVariables > MAXVARS )
+  {
+    WerrorS("resMatrixSparse::resMatrixSparse: To many variables!");
+    return;
+  }
+
+  rmat= NULL;
+  numSet0= 0;
+
+  if ( special == SNONE ) linPolyS= 0;
+  else linPolyS= special;
+
+  istate= resMatrixBase::ready;
+
+  n= pVariables;
+  idelem= IDELEMS(gls);  // should be n+1
+
+  // prepare matrix LP->LiPM for Linear Programming
+  totverts = 0;
+  for( i=0; i < idelem; i++) totverts += pLength( (gls->m)[i] );
+
+  LP = new simplex( idelem+totverts*2+5, totverts+5 ); // rows, cols
+
+  // get shift vector
+#ifdef mprTEST
+  shift[0]=0.005; shift[1]=0.003; shift[2]=0.008; shift[3]=0.005; shift[4]=0.002;
+  shift[5]=0.1; shift[6]=0.3; shift[7]=0.2; shift[8]=0.4; shift[9]=0.2;
+#else
+  randomVector( idelem, shift );
+#endif
+#ifdef mprDEBUG_PROT
+  PrintS(" shift vector: ");
+  for ( i= 1; i <= idelem; i++ ) Print(" %.12f ",(double)shift[i]);
+  PrintLn();
+#endif
+
+  // evaluate convex hull for supports of gls
+  convexHull chnp( LP );
+  Qi= chnp.newtonPolytopesP( gls );
+
+#ifdef mprMINKSUM
+  E= minkSumAll( Qi, n+1, n);
+#else
+  // get inner points
+  mayanPyramidAlg mpa( LP );
+  E= mpa.getInnerPoints( Qi, shift );
+#endif
+
+#ifdef mprDEBUG_PROT
+#ifdef mprMINKSUM
+  PrintS("(MinkSum)");
+#endif
+  PrintS("\n E = (Q_0 + ... + Q_n) \\cap \\N :\n");
+  for ( pnt= 1; pnt <= E->num; pnt++ )
+  {
+    Print("%d: <",pnt);print_exp( (*E)[pnt], E->dim );PrintS(">\n");
+  }
+  PrintLn();
+#endif
+
+#ifdef mprTEST
+  int lift[5][5];
+  lift[0][1]=3; lift[0][2]=4; lift[0][3]=8;  lift[0][4]=2;
+  lift[1][1]=6; lift[1][2]=1; lift[1][3]=7;  lift[1][4]=4;
+  lift[2][1]=2; lift[2][2]=5; lift[2][3]=9;  lift[2][4]=6;
+  lift[3][1]=2; lift[3][2]=1; lift[3][3]=9;  lift[3][4]=5;
+  lift[4][1]=3; lift[4][2]=7; lift[4][3]=1;  lift[4][4]=5;
+  // now lift everything
+  for ( i= 0; i <= n; i++ ) Qi[i]->lift( lift[i] );
+  E->dim++;
+#else
+  // now lift everything
+  for ( i= 0; i <= n; i++ ) Qi[i]->lift();
+  E->dim++;
+#endif
+
+  // run Row Content Function for every point in E
+  for ( pnt= 1; pnt <= E->num; pnt++ )
+  {
+    RC( Qi, E, pnt, shift );
+  }
+
+  // remove points not in cells
+  k= E->num;
+  for ( pnt= k; pnt > 0; pnt-- )
+  {
+    if ( (*E)[pnt]->rcPnt == NULL )
+    {
+      E->removePoint(pnt);
+      mprSTICKYPROT(ST_SPARSE_RCRJ);
+    }
+  }
+  mprSTICKYPROT("\n");
+
+#ifdef mprDEBUG_PROT
+  PrintS(" points which lie in a cell:\n");
+  for ( pnt= 1; pnt <= E->num; pnt++ )
+  {
+    Print("%d: <",pnt);print_exp( (*E)[pnt], E->dim );PrintS(">\n");
+  }
+  PrintLn();
+#endif
+
+  // unlift to old dimension, sort
+  for ( i= 0; i <= n; i++ ) Qi[i]->unlift();
+  E->unlift();
+  E->sort();
+
+#ifdef mprDEBUG_PROT
+  Print(" points with a[ij] (%d):\n",E->num);
+  for ( pnt= 1; pnt <= E->num; pnt++ )
+  {
+    Print("Punkt p \\in E[%d]: <",pnt);print_exp( (*E)[pnt], E->dim );
+    Print(">, RC(p) = (i:%d, j:%d), a[i,j] = <",(*E)[pnt]->rc.set,(*E)[pnt]->rc.pnt);
+    //print_exp( (Qi[(*E)[pnt]->rc.set])[(*E)[pnt]->rc.pnt], E->dim );PrintS("> = <");
+    print_exp( (*E)[pnt]->rcPnt, E->dim );PrintS(">\n");
+  }
+#endif
+
+  // now create matrix
+  if ( createMatrix( E ) != E->num )
+  {
+    // this can happen if the shiftvector shift is to large or not generic
+    istate= resMatrixBase::fatalError;
+    WerrorS("resMatrixSparse::resMatrixSparse: Error in resMatrixSparse::createMatrix!");
+    goto theEnd;
+    //return;
+  }
+
+ theEnd:
+  // clean up
+  for ( i= 0; i < idelem; i++ )
+  {
+    delete Qi[i];
+  }
+  omFreeSize( (ADDRESS) Qi, idelem * sizeof(pointSet*) );
+
+  delete E;
+
+  delete LP;
+}
+
+//----------------------------------------------------------------------------------------
+
+resMatrixSparse::~resMatrixSparse()
+{
+  delete uRPos;
+  idDelete( &rmat );
+}
+
+const ideal resMatrixSparse::getMatrix()
+{
+  int i,j,rp,cp;
+  poly pp,phelp,piter,pgls;
+
+  // copy original sparse res matrix
+  ideal rmat_out= idCopy(rmat);
+
+  // now fill in coeffs of f0
+  for ( i= 1; i <= numSet0; i++ )
+  {
+
+    pgls= (gls->m)[0]; // f0
+
+    // get matrix row and delete it
+    pp= (rmat_out->m)[IMATELEM(*uRPos,i,1)];
+    pDelete( &pp );
+    pp= NULL;
+    phelp= pp;
+    piter= NULL;
+
+    // u_1,..,u_k
+    cp=2;
+    while ( pNext(pgls)!=NULL )
+    {
+      phelp= pOne();
+      pSetCoeff( phelp, nCopy(pGetCoeff(pgls)) );
+      pSetComp( phelp, IMATELEM(*uRPos,i,cp) );
+      pSetmComp( phelp );
+      if ( piter!=NULL )
+      {
+        pNext(piter)= phelp;
+        piter= phelp;
+      }
+      else
+      {
+        pp= phelp;
+        piter= phelp;
+      }
+      cp++;
+      pIter( pgls );
+    }
+    // u0, now pgls points to last monom
+    phelp= pOne();
+    pSetCoeff( phelp, nCopy(pGetCoeff(pgls)) );
+    //pSetComp( phelp, IMATELEM(*uRPos,i,idelem+1) );
+    pSetComp( phelp, IMATELEM(*uRPos,i,pLength((gls->m)[0])+1) );
+    pSetmComp( phelp );
+    if (piter!=NULL) pNext(piter)= phelp;
+    else pp= phelp;
+    (rmat_out->m)[IMATELEM(*uRPos,i,1)]= pp;
+  }
+
+  return rmat_out;
+}
+
+// Fills in resMat[][] with evpoint[] and gets determinant
+//    uRPos[i][1]: row of matrix
+//    uRPos[i][idelem+1]: col of u(0)
+//    uRPos[i][2..idelem]: col of u(1) .. u(n)
+//    i= 1 .. numSet0
+const number resMatrixSparse::getDetAt( const number* evpoint )
+{
+  int i,cp,rp;
+  poly pp,phelp,piter;
+
+  mprPROTnl("smCallDet");
+
+  for ( i= 1; i <= numSet0; i++ )
+  {
+    pp= (rmat->m)[IMATELEM(*uRPos,i,1)];
+    pDelete( &pp );
+    pp= NULL;
+    phelp= pp;
+    piter= NULL;
+    // u_1,..,u_n
+    for ( cp= 2; cp <= idelem; cp++ )
+    {
+      if ( !nIsZero(evpoint[cp-1]) )
+      {
+        phelp= pOne();
+        pSetCoeff( phelp, nCopy(evpoint[cp-1]) );
+        pSetComp( phelp, IMATELEM(*uRPos,i,cp) );
+        pSetmComp( phelp );
+        if ( piter )
+        {
+          pNext(piter)= phelp;
+          piter= phelp;
+        }
+        else
+        {
+          pp= phelp;
+          piter= phelp;
+        }
+      }
+    }
+    // u0
+    phelp= pOne();
+    pSetCoeff( phelp, nCopy(evpoint[0]) );
+    pSetComp( phelp, IMATELEM(*uRPos,i,idelem+1) );
+    pSetmComp( phelp );
+    pNext(piter)= phelp;
+    (rmat->m)[IMATELEM(*uRPos,i,1)]= pp;
+  }
+
+  mprSTICKYPROT(ST__DET); // 1
+
+  poly pres= smCallDet( rmat );
+  number numres= nCopy( pGetCoeff( pres ) );
+  pDelete( &pres );
+
+  mprSTICKYPROT(ST__DET); // 2
+
+  return ( numres );
+}
+
+// Fills in resMat[][] with evpoint[] and gets determinant
+//    uRPos[i][1]: row of matrix
+//    uRPos[i][idelem+1]: col of u(0)
+//    uRPos[i][2..idelem]: col of u(1) .. u(n)
+//    i= 1 .. numSet0
+const poly resMatrixSparse::getUDet( const number* evpoint )
+{
+  int i,cp,rp;
+  poly pp,phelp,piter;
+
+  mprPROTnl("smCallDet");
+
+  for ( i= 1; i <= numSet0; i++ )
+  {
+    pp= (rmat->m)[IMATELEM(*uRPos,i,1)];
+    pDelete( &pp );
+    phelp= NULL;
+    piter= NULL;
+    for ( cp= 2; cp <= idelem; cp++ )
+    { // u1 .. un
+      if ( !nIsZero(evpoint[cp-1]) )
+      {
+        phelp= pOne();
+        pSetCoeff( phelp, nCopy(evpoint[cp-1]) );
+        pSetComp( phelp, IMATELEM(*uRPos,i,cp) );
+        pSetmComp( phelp );
+        if ( piter!=NULL )
+        {
+          pNext(piter)= phelp;
+          piter= phelp;
+        }
+        else
+        {
+          pp= phelp;
+          piter= phelp;
+        }
+      }
+    }
+    // u0
+    phelp= pOne();
+    pSetExp(phelp,1,1);
+    pSetComp( phelp, IMATELEM(*uRPos,i,idelem+1) );
+    pSetm( phelp );
+    pNext(piter)= phelp;
+    (rmat->m)[IMATELEM(*uRPos,i,1)]= pp;
+  }
+
+  mprSTICKYPROT(ST__DET); // 1
+
+  poly pres= smCallDet( rmat );
+
+  mprSTICKYPROT(ST__DET); // 2
+
+  return ( pres );
+}
+//<-
+
+//-----------------------------------------------------------------------------
+//-------------- dense resultant matrix ---------------------------------------
+//-----------------------------------------------------------------------------
+
+//-> dense resultant matrix
+//
+class resVector;
+
+/* dense resultant matrix */
+class resMatrixDense : virtual public resMatrixBase
+{
+public:
+  /**
+   * _gls: system of multivariate polynoms
+   * special: -1 -> resMatrixDense is a symbolic matrix
+   *    0,1, ... -> resMatrixDense ist eine u-Resultante, wobei special das
+   *                        lineare u-Polynom angibt
+   */
+  resMatrixDense( const ideal _gls, const int special = SNONE );
+  ~resMatrixDense();
+
+  /** column vector of matrix, index von 0 ... numVectors-1 */
+  resVector *getMVector( const int i );
+
+  /** Returns the matrix M in an usable presentation */
+  const ideal getMatrix();
+
+  /** Returns the submatrix M' of M in an usable presentation */
+  const ideal getSubMatrix();
+
+  /** Evaluate the determinant of the matrix M at the point evpoint
+   * where the ui's are replaced by the components of evpoint.
+   * Uses singclap_det from factory.
+   */
+  const number getDetAt( const number* evpoint );
+
+  /** Evaluates the determinant of the submatrix M'.
+   * Since the matrix is numerically, no evaluation point is needed.
+   * Uses singclap_det from factory.
+   */
+  const number getSubDet();
+
+private:
+  /** deactivated copy constructor */
+  resMatrixDense( const resMatrixDense & );
+
+  /** Generate the "matrix" M. Each column is presented by a resVector
+   * holding all entries for this column.
+   */
+  void generateBaseData();
+
+  /** Generates needed set of monoms, split them into sets S0, ... Sn and
+   * check if reduced/nonreduced and calculate size of submatrix.
+   */
+  void generateMonomData( int deg, intvec* polyDegs , intvec* iVO );
+
+  /** Recursively generate all homogeneous monoms of
+   * pVariables variables of degree deg.
+   */
+  void generateMonoms( poly m, int var, int deg );
+
+  /** Creates quadratic matrix M of size numVectors for later use.
+   * u0, u1, ...,un are replaced by 0.
+   * Entries equal to 0 are not initialized ( == NULL)
+   */
+  void createMatrix();
+
+private:
+  resVector *resVectorList;
+
+  int veclistmax;
+  int veclistblock;
+  int numVectors;
+  int subSize;
+
+  matrix m;
+};
+//<-
+
+//-> struct resVector
+/* Holds a row vector of the dense resultant matrix */
+struct resVector
+{
+public:
+  void init()
+  {
+    isReduced = FALSE;
+    elementOfS = SFREE;
+    mon = NULL;
+  }
+  void init( const poly m )
+  {
+    isReduced = FALSE;
+    elementOfS = SFREE;
+    mon = m;
+  }
+
+  /** index von 0 ... numVectors-1 */
+  poly getElem( const int i );
+
+  /** index von 0 ... numVectors-1 */
+  number getElemNum( const int i );
+
+  // variables
+  poly mon;
+  poly dividedBy;
+  bool isReduced;
+
+  /** number of the set S mon is element of */
+  int elementOfS;
+
+  /** holds the index of u0, u1, ..., un, if (elementOfS == linPolyS)
+   *  the size is given by pVariables
+   */
+  int *numColParNr;
+
+  /** holds the column vector if (elementOfS != linPolyS) */
+  number *numColVector;
+
+  /** size of numColVector */
+  int numColVectorSize;
+
+  number *numColVecCopy;
+};
+//<-
+
+//-> resVector::*
+poly resVector::getElem( const int i ) // inline ???
+{
+  assume( 0 < i || i > numColVectorSize );
+  poly out= pOne();
+  pSetCoeff( out, numColVector[i] );
+  pTest( out );
+  return( out );
+}
+
+number resVector::getElemNum( const int i ) // inline ??
+{
+  assume( i >= 0 && i < numColVectorSize );
+  return( numColVector[i] );
+}
+//<-
+
+//-> resMatrixDense::*
+resMatrixDense::resMatrixDense( const ideal _gls, const int special )
+  : resMatrixBase()
+{
+  int i;
+
+  sourceRing=currRing;
+  gls= idCopy( _gls );
+  linPolyS= special;
+  m=NULL;
+
+  // init all
+  generateBaseData();
+
+  totDeg= 1;
+  for ( i= 0; i < IDELEMS(gls); i++ )
+  {
+    totDeg*=pTotaldegree( (gls->m)[i] );
+  }
+
+  mprSTICKYPROT2("  resultant deg: %d\n",totDeg);
+
+  istate= resMatrixBase::ready;
+}
+
+resMatrixDense::~resMatrixDense()
+{
+  int i,j;
+  for (i=0; i < numVectors; i++)
+  {
+    pDelete( &resVectorList[i].mon );
+    pDelete( &resVectorList[i].dividedBy );
+    for ( j=0; j < resVectorList[i].numColVectorSize; j++ )
+    {
+        nDelete( resVectorList[i].numColVector+j );
+    }
+    // OB: ????? (solve_s.tst)
+    omfreeSize( (ADDRESS)resVectorList[i].numColVector,
+                numVectors * sizeof( number ) );
+    omfreeSize( (ADDRESS)resVectorList[i].numColParNr,
+                (pVariables+1) * sizeof(int) );
+  }
+
+  omFreeSize( (ADDRESS)resVectorList, veclistmax*sizeof( resVector ) );
+
+  // free matrix m
+  if ( m != NULL )
+  {
+    idDelete((ideal *)&m);
+  }
+}
+
+// mprSTICKYPROT:
+// ST_DENSE_FR: found row S0
+// ST_DENSE_NR: normal row
+void resMatrixDense::createMatrix()
+{
+  int k,i,j;
+  resVector *vecp;
+
+  m= mpNew( numVectors, numVectors );
+
+  for ( i= 1; i <= MATROWS( m ); i++ )
+    for ( j= 1; j <= MATCOLS( m ); j++ )
+    {
+      MATELEM(m,i,j)= pInit();
+      pSetCoeff0( MATELEM(m,i,j), nInit(0) );
+    }
+
+
+  for ( k= 0; k <= numVectors - 1; k++ )
+  {
+    if ( linPolyS == getMVector(k)->elementOfS )
+    {
+      mprSTICKYPROT(ST_DENSE_FR);
+      for ( i= 0; i < pVariables; i++ )
+      {
+        MATELEM(m,numVectors-k,numVectors-(getMVector(k)->numColParNr)[i])= pInit();
+      }
+    }
+    else
+    {
+      mprSTICKYPROT(ST_DENSE_NR);
+      vecp= getMVector(k);
+      for ( i= 0; i < numVectors; i++)
+      {
+        if ( !nIsZero( vecp->getElemNum(i) ) )
+        {
+          MATELEM(m,numVectors - k,i + 1)= pInit();
+          pSetCoeff0( MATELEM(m,numVectors - k,i + 1), nCopy(vecp->getElemNum(i)) );
+        }
+      }
+    }
+  } // for
+  mprSTICKYPROT("\n");
+
+#ifdef mprDEBUG_ALL
+  for ( k= numVectors - 1; k >= 0; k-- )
+  {
+    if ( linPolyS == getMVector(k)->elementOfS )
+    {
+      for ( i=0; i < pVariables; i++ )
+      {
+        Print(" %d ",(getMVector(k)->numColParNr)[i]);
+      }
+      PrintLn();
+    }
+  }
+  for (i=1; i <= numVectors; i++)
+  {
+    for (j=1; j <= numVectors; j++ )
+    {
+      pWrite0(MATELEM(m,i,j));PrintS("  ");
+    }
+    PrintLn();
+  }
+#endif
+}
+
+// mprSTICKYPROT:
+// ST_DENSE_MEM: more mem allocated
+// ST_DENSE_NMON: new monom added
+void resMatrixDense::generateMonoms( poly m, int var, int deg )
+{
+  if ( deg == 0 )
+  {
+    poly mon = pCopy( m );
+
+    if ( numVectors == veclistmax )
+    {
+      resVectorList= (resVector * )omReallocSize( resVectorList,
+                                            (veclistmax) * sizeof( resVector ),
+                                            (veclistmax + veclistblock) * sizeof( resVector ) );
+      int k;
+      for ( k= veclistmax; k < (veclistmax + veclistblock); k++ )
+        resVectorList[k].init();
+      veclistmax+= veclistblock;
+      mprSTICKYPROT(ST_DENSE_MEM);
+
+    }
+    resVectorList[numVectors].init( mon );
+    numVectors++;
+    mprSTICKYPROT(ST_DENSE_NMON);
+    return;
+  }
+  else
+  {
+    if ( var == pVariables+1 ) return;
+    poly newm = pCopy( m );
+    while ( deg >= 0 )
+    {
+      generateMonoms( newm, var+1, deg );
+      pIncrExp( newm, var );
+      pSetm( newm );
+      deg--;
+    }
+    pDelete( & newm );
+  }
+
+  return;
+}
+
+void resMatrixDense::generateMonomData( int deg, intvec* polyDegs , intvec* iVO )
+{
+  int i,j,k;
+
+  // init monomData
+  veclistblock= 512;
+  veclistmax= veclistblock;
+  resVectorList= (resVector *)omAlloc( veclistmax*sizeof( resVector ) );
+
+  // Init resVector()s
+  for ( j= veclistmax - 1; j >= 0; j-- ) resVectorList[j].init();
+  numVectors= 0;
+
+  // Generate all monoms of degree deg
+  poly start= pOne();
+  generateMonoms( start, 1, deg );
+  pDelete( & start );
+
+  mprSTICKYPROT("\n");
+
+  // Check for reduced monoms
+  // First generate polyDegs.rows() monoms
+  //  x(k)^(polyDegs[k]),  0 <= k < polyDegs.rows()
+  ideal pDegDiv= idInit( polyDegs->rows(), 1 );
+  for ( k= 0; k < polyDegs->rows(); k++ )
+  {
+    poly p= pOne();
+    pSetExp( p, k + 1, (*polyDegs)[k] );
+    pSetm( p );
+    (pDegDiv->m)[k]= p;
+  }
+
+  // Now check each monom if it is reduced.
+  // A monom monom is called reduced if there exists
+  // exactly one x(k)^(polyDegs[k]) that divides the monom.
+  int divCount;
+  for ( j= numVectors - 1; j >= 0; j-- )
+  {
+    divCount= 0;
+    for ( k= 0; k < IDELEMS(pDegDiv); k++ )
+      if ( pLmDivisibleByNoComp( (pDegDiv->m)[k], resVectorList[j].mon ) )
+        divCount++;
+    resVectorList[j].isReduced= (divCount == 1);
+  }
+
+  // create the sets S(k)s
+  // a monom x(i)^deg, deg given, is element of the set S(i)
+  // if all x(0)^(polyDegs[0]) ... x(i-1)^(polyDegs[i-1]) DONT divide
+  // x(i)^deg and only x(i)^(polyDegs[i]) divides x(i)^deg
+  bool doInsert;
+  for ( k= 0; k < iVO->rows(); k++)
+  {
+    //mprPROTInl(" ------------ var:",(*iVO)[k]);
+    for ( j= numVectors - 1; j >= 0; j-- )
+    {
+      //mprPROTPnl("testing monom",resVectorList[j].mon);
+      if ( resVectorList[j].elementOfS == SFREE )
+      {
+        //mprPROTnl("\tfree");
+        if ( pLmDivisibleByNoComp( (pDegDiv->m)[ (*iVO)[k] ], resVectorList[j].mon ) )
+        {
+          //mprPROTPnl("\tdivisible by ",(pDegDiv->m)[ (*iVO)[k] ]);
+          doInsert=TRUE;
+          for ( i= 0; i < k; i++ )
+          {
+            //mprPROTPnl("\tchecking db ",(pDegDiv->m)[ (*iVO)[i] ]);
+            if ( pLmDivisibleByNoComp( (pDegDiv->m)[ (*iVO)[i] ], resVectorList[j].mon ) )
+            {
+              //mprPROTPnl("\t and divisible by",(pDegDiv->m)[ (*iVO)[i] ]);
+              doInsert=FALSE;
+              break;
+            }
+          }
+          if ( doInsert )
+          {
+            //mprPROTInl("\t------------------> S ",(*iVO)[k]);
+            resVectorList[j].elementOfS= (*iVO)[k];
+            resVectorList[j].dividedBy= pCopy( (pDegDiv->m)[ (*iVO)[i] ] );
+          }
+        }
+      }
+    }
+  }
+
+  // size of submatrix M', equal to number of nonreduced monoms
+  // (size of matrix M is equal to number of monoms=numVectors)
+  subSize= 0;
+  int sub;
+  for ( i= 0; i < polyDegs->rows(); i++ )
+  {
+    sub= 1;
+    for ( k= 0; k < polyDegs->rows(); k++ )
+      if ( i != k ) sub*= (*polyDegs)[k];
+    subSize+= sub;
+  }
+  subSize= numVectors - subSize;
+
+  // pDegDiv wieder freigeben!
+  idDelete( &pDegDiv );
+
+#ifdef mprDEBUG_ALL
+  // Print a list of monoms and their properties
+  PrintS("// \n");
+  for ( j= numVectors - 1; j >= 0; j-- )
+  {
+    Print("// %s, S(%d),  db ",
+          resVectorList[j].isReduced?"reduced":"nonreduced",
+          resVectorList[j].elementOfS);
+    pWrite0(resVectorList[j].dividedBy);
+    PrintS("  monom ");
+    pWrite(resVectorList[j].mon);
+  }
+  Print("// size: %d, subSize: %d\n",numVectors,subSize);
+#endif
+}
+
+void resMatrixDense::generateBaseData()
+{
+  int k,j,i;
+  number matEntry;
+  poly pmatchPos;
+  poly pi,factor,pmp;
+
+  // holds the degrees of F0, F1, ..., Fn
+  intvec polyDegs( IDELEMS(gls) );
+  for ( k= 0; k < IDELEMS(gls); k++ )
+    polyDegs[k]= pTotaldegree( (gls->m)[k] );
+
+  // the internal Variable Ordering
+  // make sure that the homogenization variable goes last!
+  intvec iVO( pVariables );
+  if ( linPolyS != SNONE )
+  {
+    iVO[pVariables - 1]= linPolyS;
+    int p=0;
+    for ( k= pVariables - 1; k >= 0; k-- )
+    {
+      if ( k != linPolyS )
+      {
+        iVO[p]= k;
+        p++;
+      }
+    }
+  }
+  else
+  {
+    linPolyS= 0;
+    for ( k= 0; k < pVariables; k++ )
+      iVO[k]= pVariables - k - 1;
+  }
+
+  // the critical degree d= sum( deg(Fi) ) - n
+  int sumDeg= 0;
+  for ( k= 0; k < polyDegs.rows(); k++ )
+    sumDeg+= polyDegs[k];
+  sumDeg-= polyDegs.rows() - 1;
+
+  // generate the base data
+  generateMonomData( sumDeg, &polyDegs, &iVO );
+
+  // generate "matrix"
+  for ( k= numVectors - 1; k >= 0; k-- )
+  {
+    if ( resVectorList[k].elementOfS != linPolyS )
+    {
+      // column k is a normal column with numerical or symbolic entries
+      // init stuff
+      resVectorList[k].numColParNr= NULL;
+      resVectorList[k].numColVectorSize= numVectors;
+      resVectorList[k].numColVector= (number *)omAlloc( numVectors*sizeof( number ) );
+      for ( i= 0; i < numVectors; i++ ) resVectorList[k].numColVector[i]= nInit(0);
+
+      // compute row poly
+      poly pi= ppMult_qq( (gls->m)[ resVectorList[k].elementOfS ] , resVectorList[k].mon );
+      pi= pDivideM( pCopy( pi ), pCopy( resVectorList[k].dividedBy ) );
+
+      // fill in "matrix"
+      while ( pi != NULL )
+      {
+        matEntry= nCopy(pGetCoeff(pi));
+        pmatchPos= pLmInit( pi );
+        pSetCoeff0( pmatchPos, nInit(1) );
+
+        for ( i= 0; i < numVectors; i++)
+          if ( pLmEqual( pmatchPos, resVectorList[i].mon ) )
+            break;
+
+        resVectorList[k].numColVector[numVectors - i - 1] = nCopy(matEntry);
+
+        pDelete( &pmatchPos );
+        nDelete( &matEntry );
+
+        pIter( pi );
+      }
+      pDelete( &pi );
+    }
+    else
+    {
+      // column is a special column, i.e. is generated by S0 and F0
+      // safe only the positions of the ui's in the column
+      //mprPROTInl(" setup of numColParNr ",k);
+      resVectorList[k].numColVectorSize= 0;
+      resVectorList[k].numColVector= NULL;
+      resVectorList[k].numColParNr= (int *)omAlloc0( (pVariables+1) * sizeof(int) );
+
+      pi= (gls->m)[ resVectorList[k].elementOfS ];
+      factor= pDivideM( pCopy( resVectorList[k].mon ), pCopy( resVectorList[k].dividedBy ) );
+
+      j=0;
+      while ( pi  != NULL )
+      { // fill in "matrix"
+        pmp= pMult( pCopy( factor ), pHead( pi ) );
+        pTest( pmp );
+
+        for ( i= 0; i < numVectors; i++)
+          if ( pLmEqual( pmp, resVectorList[i].mon ) )
+            break;
+
+        resVectorList[k].numColParNr[j]= i;
+        pDelete( &pmp );
+        pIter( pi );
+        j++;
+      }
+      pDelete( &pi );
+      pDelete( &factor );
+    }
+  } // for ( k= numVectors - 1; k >= 0; k-- )
+
+  mprSTICKYPROT2(" size of matrix:    %d\n",numVectors);
+  mprSTICKYPROT2(" size of submatrix: %d\n",subSize);
+
+  // create the matrix M
+  createMatrix();
+
+}
+
+resVector *resMatrixDense::getMVector(const int i)
+{
+  assume( i >= 0 && i < numVectors );
+  return &resVectorList[i];
+}
+
+const ideal resMatrixDense::getMatrix()
+{
+  int k,i,j;
+
+  // copy matrix
+  matrix resmat= mpNew(numVectors,numVectors);
+  poly p;
+  for (i=1; i <= numVectors; i++)
+  {
+    for (j=1; j <= numVectors; j++ )
+    {
+      p=MATELEM(m,i,j);
+      if (( p!=NULL)
+      && (!nIsZero(pGetCoeff(p)))
+      && (pGetCoeff(p)!=NULL)
+      )
+      {
+        MATELEM(resmat,i,j)= pCopy( p );
+      }
+    }
+  }
+  for (i=0; i < numVectors; i++)
+  {
+    if ( resVectorList[i].elementOfS == linPolyS )
+    {
+      for (j=1; j <= pVariables; j++ )
+      {
+        if ( MATELEM(resmat,numVectors-i,
+                     numVectors-resVectorList[i].numColParNr[j-1])!=NULL )
+          pDelete( &MATELEM(resmat,numVectors-i,numVectors-resVectorList[i].numColParNr[j-1]) );
+        MATELEM(resmat,numVectors-i,numVectors-resVectorList[i].numColParNr[j-1])= pOne();
+        // FIX ME
+        if ( FALSE )
+        {
+          pSetCoeff( MATELEM(resmat,numVectors-i,numVectors-resVectorList[i].numColParNr[j-1]), nPar(j) );
+        }
+        else
+        {
+          pSetExp( MATELEM(resmat,numVectors-i,numVectors-resVectorList[i].numColParNr[j-1]), j, 1 );
+          pSetm(MATELEM(resmat,numVectors-i,numVectors-resVectorList[i].numColParNr[j-1]));
+        }
+      }
+    }
+  }
+
+  // obachman: idMatrix2Module frees resmat !!
+  ideal resmod= idMatrix2Module(resmat);
+  return resmod;
+}
+
+const ideal resMatrixDense::getSubMatrix()
+{
+  int k,i,j,l;
+  resVector *vecp;
+
+  // generate quadratic matrix resmat of size subSize
+  matrix resmat= mpNew( subSize, subSize );
+
+  j=1;
+  for ( k= numVectors - 1; k >= 0; k-- )
+  {
+    vecp= getMVector(k);
+    if ( vecp->isReduced ) continue;
+    l=1;
+    for ( i= numVectors - 1; i >= 0; i-- )
+    {
+      if ( getMVector(i)->isReduced ) continue;
+      if ( !nIsZero(vecp->getElemNum(numVectors - i - 1)) )
+      {
+        MATELEM(resmat,j,l)= pCopy( vecp->getElem(numVectors-i-1) );
+      }
+      l++;
+    }
+    j++;
+  }
+
+  // obachman: idMatrix2Module frees resmat !!
+  ideal resmod= idMatrix2Module(resmat);
+  return resmod;
+}
+
+const number resMatrixDense::getDetAt( const number* evpoint )
+{
+  int k,i,j;
+
+  // copy evaluation point into matrix
+  // p0, p1, ..., pn replace u0, u1, ..., un
+  for ( k= numVectors - 1; k >= 0; k-- )
+  {
+    if ( linPolyS == getMVector(k)->elementOfS )
+    {
+      for ( i= 0; i < pVariables; i++ )
+      {
+        pSetCoeff( MATELEM(m,numVectors-k,numVectors-(getMVector(k)->numColParNr)[i]),
+                   nCopy(evpoint[i]) );
+      }
+    }
+  }
+
+  mprSTICKYPROT(ST__DET);
+
+  // evaluate determinant of matrix m using factory singclap_det
+#ifdef HAVE_FACTORY
+  poly res= singclap_det( m );
+#else
+  poly res= NULL;
+#endif
+
+  // avoid errors for det==0
+  number numres;
+  if ( (res!=NULL)  && (!nIsZero(pGetCoeff( res ))) )
+  {
+    numres= nCopy( pGetCoeff( res ) );
+  }
+  else
+  {
+    numres= nInit(0);
+    mprPROT("0");
+  }
+  pDelete( &res );
+
+  mprSTICKYPROT(ST__DET);
+
+  return( numres );
+}
+
+const number resMatrixDense::getSubDet()
+{
+  int k,i,j,l;
+  resVector *vecp;
+
+  // generate quadratic matrix mat of size subSize
+  matrix mat= mpNew( subSize, subSize );
+
+  for ( i= 1; i <= MATROWS( mat ); i++ )
+  {
+    for ( j= 1; j <= MATCOLS( mat ); j++ )
+    {
+      MATELEM(mat,i,j)= pInit();
+      pSetCoeff0( MATELEM(mat,i,j), nInit(0) );
+    }
+  }
+  j=1;
+  for ( k= numVectors - 1; k >= 0; k-- )
+  {
+    vecp= getMVector(k);
+    if ( vecp->isReduced ) continue;
+    l=1;
+    for ( i= numVectors - 1; i >= 0; i-- )
+    {
+      if ( getMVector(i)->isReduced ) continue;
+      if ( vecp->getElemNum(numVectors - i - 1) && !nIsZero(vecp->getElemNum(numVectors - i - 1)) )
+      {
+        pSetCoeff(MATELEM(mat, j , l ), nCopy(vecp->getElemNum(numVectors - i - 1)));
+      }
+      /* else
+      {
+           MATELEM(mat, j , l )= pOne();
+           pSetCoeff(MATELEM(mat, j , l ), nInit(0) );
+      }
+      */
+      l++;
+    }
+    j++;
+  }
+
+#ifdef HAVE_FACTORY
+  poly res= singclap_det( mat );
+#else
+  poly res= NULL;
+#endif
+
+  number numres;
+  if ((res != NULL) && (!nIsZero(pGetCoeff( res ))) )
+  {
+    numres= nCopy(pGetCoeff( res ));
+  }
+  else
+  {
+    numres= nInit(0);
+  }
+  pDelete( &res );
+  return numres;
+}
+//<--
+
+//-----------------------------------------------------------------------------
+//-------------- uResultant ---------------------------------------------------
+//-----------------------------------------------------------------------------
+
+#define MAXEVPOINT 1000000 // 0x7fffffff
+//#define MPR_MASI
+
+//-> unsigned long over(unsigned long n,unsigned long d)
+// Calculates (n+d \over d) using gmp functionality
+//
+unsigned long over( const unsigned long n , const unsigned long d )
+{ // (d+n)! / ( d! n! )
+  mpz_t res;
+  mpz_init(res);
+  mpz_t m,md,mn;
+  mpz_init(m);mpz_set_ui(m,1);
+  mpz_init(md);mpz_set_ui(md,1);
+  mpz_init(mn);mpz_set_ui(mn,1);
+
+  mpz_fac_ui(m,n+d);
+  mpz_fac_ui(md,d);
+  mpz_fac_ui(mn,n);
+
+  mpz_mul(res,md,mn);
+  mpz_tdiv_q(res,m,res);
+
+  mpz_clear(m);mpz_clear(md);mpz_clear(mn);
+
+  unsigned long result = mpz_get_ui(res);
+  mpz_clear(res);
+
+  return result;
+}
+//<-
+
+//-> uResultant::*
+uResultant::uResultant( const ideal _gls, const resMatType _rmt, BOOLEAN extIdeal )
+  : rmt( _rmt )
+{
+  if ( extIdeal )
+  {
+    // extend given ideal by linear poly F0=u0x0 + u1x1 +...+ unxn
+    gls= extendIdeal( _gls, linearPoly( rmt ), rmt );
+    n= IDELEMS( gls );
+  }
+  else
+    gls= idCopy( _gls );
+
+  switch ( rmt )
+  {
+  case sparseResMat:
+    resMat= new resMatrixSparse( gls );
+    break;
+  case denseResMat:
+#ifdef HAVE_FACTORY
+    resMat= new resMatrixDense( gls );
+    break;
+#endif
+  default:
+    WerrorS("uResultant::uResultant: Unknown resultant matrix type choosen!");
+  }
+}
+
+uResultant::~uResultant( )
+{
+  delete resMat;
+}
+
+ideal uResultant::extendIdeal( const ideal gls, poly linPoly, const resMatType rmt )
+{
+  ideal newGls= idCopy( gls );
+  newGls->m= (poly *)omReallocSize( newGls->m,
+                              IDELEMS(gls) * sizeof(poly),
+                              (IDELEMS(gls) + 1) * sizeof(poly) );
+  IDELEMS(newGls)++;
+
+  switch ( rmt )
+  {
+  case sparseResMat:
+  case denseResMat:
+    {
+      int i;
+      for ( i= IDELEMS(newGls)-1; i > 0; i-- )
+      {
+        newGls->m[i]= newGls->m[i-1];
+      }
+      newGls->m[0]= linPoly;
+    }
+    break;
+  default:
+    WerrorS("uResultant::extendIdeal: Unknown resultant matrix type choosen!");
+  }
+
+  return( newGls );
+}
+
+poly uResultant::linearPoly( const resMatType rmt )
+{
+  int i,j;
+
+  poly newlp= pOne();
+  poly actlp, rootlp= newlp;
+
+  for ( i= 1; i <= pVariables; i++ )
+  {
+    actlp= newlp;
+    pSetExp( actlp, i, 1 );
+    pSetm( actlp );
+    newlp= pOne();
+    actlp->next= newlp;
+  }
+  actlp->next= NULL;
+  pDelete( &newlp );
+
+  if ( rmt == sparseResMat )
+  {
+    newlp= pOne();
+    actlp->next= newlp;
+    newlp->next= NULL;
+  }
+  return ( rootlp );
+}
+
+poly uResultant::interpolateDense( const number subDetVal )
+{
+  int i,j,p;
+  long tdg;
+
+  // D is a Polynom homogeneous in the coeffs of F0 and of degree tdg = d0*d1*...*dn
+  tdg= resMat->getDetDeg();
+
+  // maximum number of terms in polynom D (homogeneous, of degree tdg)
+  // long mdg= (facul(tdg+n-1) / facul( tdg )) / facul( n - 1 );
+  long mdg= over( n-1, tdg );
+
+  // maxiaml number of terms in a polynom of degree tdg
+  long l=(long)pow( tdg+1, n );
+
+#ifdef mprDEBUG_PROT
+  Print("// total deg of D: tdg %d\n",tdg);
+  Print("// maximum number of terms in D: mdg: %d\n",mdg);
+  Print("// maximum number of terms in polynom of deg tdg: l %d\n",l);
+#endif
+
+  // we need mdg results of D(p0,p1,...,pn)
+  number *presults;
+  presults= (number *)omAlloc( mdg * sizeof( number ) );
+  for (i=0; i < mdg; i++) presults[i]= nInit(0);
+
+  number *pevpoint= (number *)omAlloc( n * sizeof( number ) );
+  number *pev= (number *)omAlloc( n * sizeof( number ) );
+  for (i=0; i < n; i++) pev[i]= nInit(0);
+
+  mprPROTnl("// initial evaluation point: ");
+  // initial evaluatoin point
+  p=1;
+  for (i=0; i < n; i++)
+  {
+    // init pevpoint with primes 3,5,7,11, ...
+    p= nextPrime( p );
+    pevpoint[i]=nInit( p );
+    nTest(pevpoint[i]);
+    mprPROTNnl(" ",pevpoint[i]);
+  }
+
+  // evaluate the determinant in the points pev^0, pev^1, ..., pev^mdg
+  mprPROTnl("// evaluating:");
+  for ( i=0; i < mdg; i++ )
+  {
+    for (j=0; j < n; j++)
+    {
+      nDelete( &pev[j] );
+      nPower(pevpoint[j],i,&pev[j]);
+      mprPROTN(" ",pev[j]);
+    }
+    mprPROTnl("");
+
+    nDelete( &presults[i] );
+    presults[i]=resMat->getDetAt( pev );
+
+    mprSTICKYPROT(ST_BASE_EV);
+  }
+  mprSTICKYPROT("\n");
+
+  // now interpolate using vandermode interpolation
+  mprPROTnl("// interpolating:");
+  number *ncpoly;
+  {
+    vandermonde vm( mdg, n, tdg, pevpoint );
+    ncpoly= vm.interpolateDense( presults );
+  }
+
+  if ( subDetVal != NULL )
+  {   // divide by common factor
+    number detdiv;
+    for ( i= 0; i <= mdg; i++ )
+    {
+      detdiv= nDiv( ncpoly[i], subDetVal );
+      nNormalize( detdiv );
+      nDelete( &ncpoly[i] );
+      ncpoly[i]= detdiv;
+    }
+  }
+
+#ifdef mprDEBUG_ALL
+  PrintLn();
+  for ( i=0; i < mdg; i++ )
+  {
+    nPrint(ncpoly[i]); PrintS(" --- ");
+  }
+  PrintLn();
+#endif
+
+  // prepare ncpoly for later use
+  number nn=nInit(0);
+  for ( i=0; i < mdg; i++ )
+  {
+    if ( nEqual(ncpoly[i],nn) )
+    {
+      nDelete( &ncpoly[i] );
+      ncpoly[i]=NULL;
+    }
+  }
+  nDelete( &nn );
+
+  // create poly presenting the determinat of the uResultant
+  intvec exp( n );
+  for ( i= 0; i < n; i++ ) exp[i]=0;
+
+  poly result= NULL;
+
+  long sum=0;
+  long c=0;
+
+  for ( i=0; i < l; i++ )
+  {
+    if ( sum == tdg )
+    {
+      if ( !nIsZero(ncpoly[c]) )
+      {
+        poly p= pOne();
+        if ( rmt == denseResMat )
+        {
+          for ( j= 0; j < n; j++ ) pSetExp( p, j+1, exp[j] );
+        }
+        else if ( rmt == sparseResMat )
+        {
+          for ( j= 1; j < n; j++ ) pSetExp( p, j, exp[j] );
+        }
+        pSetCoeff( p, ncpoly[c] );
+        pSetm( p );
+        if (result!=NULL) result= pAdd( result, p );
+        else result=  p;
+      }
+      c++;
+    }
+    sum=0;
+    exp[0]++;
+    for ( j= 0; j < n - 1; j++ )
+    {
+      if ( exp[j] > tdg )
+      {
+        exp[j]= 0;
+        exp[j + 1]++;
+      }
+      sum+=exp[j];
+    }
+    sum+=exp[n-1];
+  }
+
+  pTest( result );
+
+  return result;
+}
+
+rootContainer ** uResultant::interpolateDenseSP( BOOLEAN matchUp, const number subDetVal )
+{
+  int i,j,p,uvar;
+  long tdg;
+  int loops= (matchUp?n-2:n-1);
+
+  mprPROTnl("uResultant::interpolateDenseSP");
+
+  tdg= resMat->getDetDeg();
+
+  // evaluate D in tdg+1 distinct points, so
+  // we need tdg+1 results of D(p0,1,0,...,0) =
+  //              c(0)*u0^tdg + c(1)*u0^tdg-1 + ... + c(tdg-1)*u0 + c(tdg)
+  number *presults;
+  presults= (number *)omAlloc( (tdg + 1) * sizeof( number ) );
+  for ( i=0; i <= tdg; i++ ) presults[i]= nInit(0);
+
+  rootContainer ** roots;
+  roots= (rootContainer **) omAlloc( loops * sizeof(rootContainer*) );
+  for ( i=0; i < loops; i++ ) roots[i]= new rootContainer(); // 0..n-2
+
+  number *pevpoint= (number *)omAlloc( n * sizeof( number ) );
+  for (i=0; i < n; i++) pevpoint[i]= nInit(0);
+
+  number *pev= (number *)omAlloc( n * sizeof( number ) );
+  for (i=0; i < n; i++) pev[i]= nInit(0);
+
+  // now we evaluate D(u0,-1,0,...0), D(u0,0,-1,0,...,0), ..., D(u0,0,..,0,-1)
+  // or D(u0,k1,k2,0,...,0), D(u0,k1,k2,k3,0,...,0), ..., D(u0,k1,k2,k3,...,kn)
+  // this gives us n-1 evaluations
+  p=3;
+  for ( uvar= 0; uvar < loops; uvar++ )
+  {
+    // generate initial evaluation point
+    if ( matchUp )
+    {
+      for (i=0; i < n; i++)
+      {
+        // prime(random number) between 1 and MAXEVPOINT
+        nDelete( &pevpoint[i] );
+        if ( i == 0 )
+        {
+          //p= nextPrime( p );
+          pevpoint[i]= nInit( p );
+        }
+        else if ( i <= uvar + 2 )
+        {
+          pevpoint[i]=nInit(1+siRand()%MAXEVPOINT);
+          //pevpoint[i]=nInit(383);
+        }
+        else
+          pevpoint[i]=nInit(0);
+        mprPROTNnl(" ",pevpoint[i]);
+      }
+    }
+    else
+    {
+      for (i=0; i < n; i++)
+      {
+        // init pevpoint with  prime,0,...0,1,0,...,0
+        nDelete( &pevpoint[i] );
+        if ( i == 0 )
+        {
+          //p=nextPrime( p );
+          pevpoint[i]=nInit( p );
+        }
+        else
+        {
+          if ( i == (uvar + 1) ) pevpoint[i]= nInit(-1);
+          else pevpoint[i]= nInit(0);
+        }
+        mprPROTNnl(" ",pevpoint[i]);
+      }
+    }
+
+    // prepare aktual evaluation point
+    for (i=0; i < n; i++)
+    {
+      nDelete( &pev[i] );
+      pev[i]= nCopy( pevpoint[i] );
+    }
+    // evaluate the determinant in the points pev^0, pev^1, ..., pev^tdg
+    for ( i=0; i <= tdg; i++ )
+    {
+      nDelete( &pev[0] );
+      nPower(pevpoint[0],i,&pev[0]);          // new evpoint
+
+      nDelete( &presults[i] );
+      presults[i]=resMat->getDetAt( pev );   // evaluate det at point evpoint
+
+      mprPROTNnl("",presults[i]);
+
+      mprSTICKYPROT(ST_BASE_EV);
+      mprPROTI("",tdg-i);
+    }
+    mprSTICKYPROT("\n");
+
+    // now interpolate
+    vandermonde vm( tdg + 1, 1, tdg, pevpoint, FALSE );
+    number *ncpoly= vm.interpolateDense( presults );
+
+    if ( subDetVal != NULL )
+    {  // divide by common factor
+      number detdiv;
+      for ( i= 0; i <= tdg; i++ )
+      {
+        detdiv= nDiv( ncpoly[i], subDetVal );
+        nNormalize( detdiv );
+        nDelete( &ncpoly[i] );
+        ncpoly[i]= detdiv;
+      }
+    }
+
+#ifdef mprDEBUG_ALL
+    PrintLn();
+    for ( i=0; i <= tdg; i++ )
+    {
+      nPrint(ncpoly[i]); PrintS(" --- ");
+    }
+    PrintLn();
+#endif
+
+    // save results
+    roots[uvar]->fillContainer( ncpoly, pevpoint, uvar+1, tdg,
+                                (matchUp?rootContainer::cspecialmu:rootContainer::cspecial),
+                                loops );
+  }
+
+  // free some stuff: pev, presult
+  for ( i=0; i < n; i++ ) nDelete( pev + i );
+  omFreeSize( (ADDRESS)pev, n * sizeof( number ) );
+
+  for ( i=0; i <= tdg; i++ ) nDelete( presults+i );
+  omFreeSize( (ADDRESS)presults, (tdg + 1) * sizeof( number ) );
+
+  return roots;
+}
+
+rootContainer ** uResultant::specializeInU( BOOLEAN matchUp, const number subDetVal )
+{
+  int i,j,p,uvar;
+  long tdg;
+  poly pures,piter;
+  int loops=(matchUp?n-2:n-1);
+
+  mprPROTnl("uResultant::specializeInU");
+
+  tdg= resMat->getDetDeg();
+
+  rootContainer ** roots;
+  roots= (rootContainer **) omAlloc( loops * sizeof(rootContainer*) );
+  for ( i=0; i < loops; i++ ) roots[i]= new rootContainer(); // 0..n-2
+
+  number *pevpoint= (number *)omAlloc( n * sizeof( number ) );
+  for (i=0; i < n; i++) pevpoint[i]= nInit(0);
+
+  // now we evaluate D(u0,-1,0,...0), D(u0,0,-1,0,...,0), ..., D(u0,0,..,0,-1)
+  // or D(u0,k1,k2,0,...,0), D(u0,k1,k2,k3,0,...,0), ..., D(u0,k1,k2,k3,...,kn)
+  p=3;
+  for ( uvar= 0; uvar < loops; uvar++ )
+  {
+    // generate initial evaluation point
+    if ( matchUp )
+    {
+      for (i=0; i < n; i++)
+      {
+        // prime(random number) between 1 and MAXEVPOINT
+        nDelete( &pevpoint[i] );
+        if ( i <= uvar + 2 )
+        {
+          pevpoint[i]=nInit(1+siRand()%MAXEVPOINT);
+          //pevpoint[i]=nInit(383);
+        } else pevpoint[i]=nInit(0);
+        mprPROTNnl(" ",pevpoint[i]);
+      }
+    }
+    else
+    {
+      for (i=0; i < n; i++)
+      {
+        // init pevpoint with  prime,0,...0,-1,0,...,0
+        nDelete( &(pevpoint[i]) );
+        if ( i == (uvar + 1) ) pevpoint[i]= nInit(-1);
+        else pevpoint[i]= nInit(0);
+        mprPROTNnl(" ",pevpoint[i]);
+      }
+    }
+
+    pures= resMat->getUDet( pevpoint );
+
+    number *ncpoly= (number *)omAlloc( (tdg+1) * sizeof(number) );
+
+#ifdef MPR_MASI
+    BOOLEAN masi=true;
+#endif
+
+    piter= pures;
+    for ( i= tdg; i >= 0; i-- )
+    {
+      //if ( piter ) Print("deg %d, pDeg(piter) %d\n",i,pTotaldegree(piter));
+      if ( piter && pTotaldegree(piter) == i )
+      {
+        ncpoly[i]= nCopy( pGetCoeff( piter ) );
+        pIter( piter );
+#ifdef MPR_MASI
+        masi=false;
+#endif
+      }
+      else
+      {
+        ncpoly[i]= nInit(0);
+      }
+      mprPROTNnl("", ncpoly[i] );
+    }
+#ifdef MPR_MASI
+    if ( masi ) mprSTICKYPROT("MASI");
+#endif
+
+    mprSTICKYPROT(ST_BASE_EV); // .
+
+    if ( subDetVal != NULL ) {  // divide by common factor
+      number detdiv;
+      for ( i= 0; i <= tdg; i++ )
+      {
+        detdiv= nDiv( ncpoly[i], subDetVal );
+        nNormalize( detdiv );
+        nDelete( &ncpoly[i] );
+        ncpoly[i]= detdiv;
+      }
+    }
+
+    pDelete( &pures );
+
+    // save results
+    roots[uvar]->fillContainer( ncpoly, pevpoint, uvar+1, tdg,
+                                (matchUp?rootContainer::cspecialmu:rootContainer::cspecial),
+                                loops );
+  }
+
+  mprSTICKYPROT("\n");
+
+  // free some stuff: pev, presult
+  for ( i=0; i < n; i++ ) nDelete( pevpoint + i );
+  omFreeSize( (ADDRESS)pevpoint, n * sizeof( number ) );
+
+  return roots;
+}
+
+int uResultant::nextPrime( const int i )
+{
+  int init=i;
+  int ii=i+2;
+  int j= IsPrime( ii );
+  while ( j <= init )
+  {
+    ii+=2;
+    j= IsPrime( ii );
+  }
+  return j;
+}
+//<-
+
+//-----------------------------------------------------------------------------
+
+//-> loNewtonPolytope(...)
+ideal loNewtonPolytope( const ideal id )
+{
+  simplex * LP;
+  int i;
+  int n,totverts,idelem;
+  ideal idr;
+
+  n= pVariables;
+  idelem= IDELEMS(id);  // should be n+1
+
+  totverts = 0;
+  for( i=0; i < idelem; i++) totverts += pLength( (id->m)[i] );
+
+  LP = new simplex( idelem+totverts*2+5, totverts+5 ); // rows, cols
+
+  // evaluate convex hull for supports of id
+  convexHull chnp( LP );
+  idr = chnp.newtonPolytopesI( id );
+
+  delete LP;
+
+  return idr;
+}
+//<-
+
+//%e
+
+//-----------------------------------------------------------------------------
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-1: "make installg" ***
+// compile-command-2: "make install" ***
+// End: ***
+
+// in folding: C-c x
+// leave fold: C-c y
+//   foldmode: F10
Index: kernel/mpr_base.h
===================================================================
--- kernel/mpr_base.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/mpr_base.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,124 @@
+#ifndef MPR_BASE_H
+#define MPR_BASE_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: mpr_base.h,v 1.1.1.1 2003-10-06 12:15:57 Singular Exp $ */
+
+/*
+* ABSTRACT - multipolynomial resultants - resultant matrices
+*            ( sparse, dense, u-resultant solver )
+*/
+
+#include "mpr_numeric.h"
+
+#define SNONE -1
+#define SFREE -2
+
+//%s
+//-> class resMatrixBase
+/**
+ * Base class for sparse and dense u-Resultant computation
+ */
+class resMatrixBase
+{
+public:
+  /* state of the resultant */
+  enum IStateType { none, ready, notInit, fatalError, sparseError };
+
+  resMatrixBase() : istate(notInit), totDeg(0) {}
+  virtual ~resMatrixBase() {}
+
+  virtual const ideal getMatrix() { return NULL; }
+  virtual const ideal getSubMatrix() { return NULL; }
+
+  virtual const poly getUDet( const number* evpoint ) { return NULL; }
+
+  virtual const number getDetAt( const number* evpoint ) { return NULL; }
+  virtual const number getSubDet() { return NULL; }
+
+  virtual const long getDetDeg() const { return totDeg; }
+
+  virtual const IStateType initState() const { return istate; }
+
+protected:
+  IStateType istate;
+
+  ideal gls;
+  int linPolyS;
+  ring sourceRing;
+
+  int totDeg;
+
+private:
+  /* disables the copy constructor */
+  resMatrixBase( const resMatrixBase & );
+};
+//<-
+
+//-> class uResultant
+/**
+ * Base class for solving 0-dim poly systems using u-resultant
+ */
+class uResultant
+{
+public:
+  enum resMatType { none, sparseResMat, denseResMat };
+
+  uResultant( const ideal _gls, const resMatType _rmt= sparseResMat, BOOLEAN extIdeal= true );
+  ~uResultant();
+
+  poly interpolateDense( const number subDetVal= NULL );
+
+  /* Interpolates n+1 determinat polys for coeff specializations. */
+  rootContainer ** interpolateDenseSP( BOOLEAN matchUp= false, const number subDetVal= NULL );
+
+  /* Uses Bareiss */
+  rootContainer ** specializeInU( BOOLEAN matchUp= false, const number subDetVal= NULL );
+
+  resMatrixBase * accessResMat() { return resMat; }
+
+private:
+  /* deactivated copy constructor */
+  uResultant( const uResultant & );
+
+  ideal extendIdeal( const ideal gls, poly linPoly, const resMatType rmt );
+  poly linearPoly( const resMatType rmt );
+  int nextPrime( const int p );
+
+  ideal gls;
+  int n;
+
+  resMatType rmt;        // sparse or dense resultant matrix ?
+  resMatrixBase *resMat; // pointer to base resultant matrix class
+};
+//<-
+uResultant::resMatType determineMType( int imtype );
+enum mprState
+{
+    mprOk,
+    mprWrongRType,
+    mprHasOne,
+    mprInfNumOfVars,
+    mprNotReduced,
+    mprNotZeroDim,
+    mprNotHomog,
+    mprUnSupField
+};
+
+mprState mprIdealCheck( const ideal theIdeal,
+                        const char * name,
+                        uResultant::resMatType mtype,
+                        BOOLEAN rmatrix= false );
+
+ideal loNewtonPolytope( const ideal id );
+
+extern size_t gmp_output_digits;
+//%e
+#endif MPR_BASE_H
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-2: "make install" ***
+// compile-command: "make installg" ***
+// End: ***
Index: kernel/mpr_complex.cc
===================================================================
--- kernel/mpr_complex.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/mpr_complex.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,731 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: mpr_complex.cc,v 1.1.1.1 2003-10-06 12:15:55 Singular Exp $ */
+
+/*
+* ABSTRACT - multipolynomial resultants - real floating-point numbers using gmp
+*            and complex numbers based on pairs of real floating-point numbers
+*
+*/
+
+// WARNING! ALWAYS use omAlloc and FreeL when alloc. memory for some char* !!
+
+#include "mod2.h"
+//#ifdef HAVE_MPR
+#include "structs.h"
+#include "febase.h"
+#include "omalloc.h"
+#include "numbers.h"
+#include "longrat.h"
+#include <math.h>
+#include "mpr_complex.h"
+
+//%s
+// this was copied form longrat0.cc
+// and will be used in numberToFloat.
+// Make sure that it is up to date!!
+#define SR_HDL(A) ((long)(A))
+#define SR_INT    1
+#define SR_TO_INT(SR) (((long)SR) >> 2)
+
+#define SIGN_PLUS  1
+#define SIGN_SPACE 2
+#define SIGN_EMPTY 4
+
+#define EXTRABYTES 4
+
+#define DEFPREC        20         // minimum number of digits (output operations)
+size_t gmp_output_digits= DEFPREC;
+
+extern int mmInit(void);
+int dummy=mmInit();
+static gmp_float gmpRel(0.0);
+static gmp_float diff(0.0);
+
+
+/** Set size of mantissa
+ *  digits - the number of output digits (basis 10)
+ *  the size of mantissa consists of two parts:
+ *    the "output" part a and the "rest" part b.
+ *  According to the GMP-precision digits is
+ *  recomputed to bits (basis 2).
+ *  Two numbers a, b are equal if
+ *    | a - b | < | a | * 0.1^digits .
+ *  In this case we have a - b = 0 .
+ *  The epsilon e is e=0.1^(digits+rest) with
+ *  1+e != 1, but 1+0.1*e = 1.
+ */
+void setGMPFloatDigits( size_t digits, size_t rest )
+{
+  size_t bits = 1 + (size_t) ((float)digits * 3.5);
+  size_t rb = 1 + (size_t) ((float)rest * 3.5);
+  size_t db = bits+rb;
+  gmp_output_digits= digits;
+  mpf_set_default_prec( db );
+  mpf_set_prec(*diff._mpfp(),32);
+  mpf_set_prec(*gmpRel._mpfp(),32);
+  mpf_set_d(*gmpRel._mpfp(),0.1);
+  mpf_pow_ui(*gmpRel._mpfp(),*gmpRel._mpfp(),digits);
+}
+
+size_t getGMPFloatDigits()
+{
+  return gmp_output_digits;
+}
+
+void gmp_float::setFromStr( char * in )
+{
+  // gmp doesn't understand number which begin with "." -- it needs 0.
+  // so, insert the zero
+  if (*in == '.')
+  {
+    int len = strlen(in)+2;
+    char* c_in = (char*) omAlloc(len);
+    *c_in = '0';
+    strcpy(&(c_in[1]), in);
+
+    mpf_set_str( t, c_in, 10 );
+    omFreeSize((void*)c_in, len);
+  }
+  else
+  {
+    mpf_set_str( t, in, 10 );
+  }
+}
+
+
+// <gmp_float> = <gmp_float> operator <gmp_float>
+gmp_float operator + ( const gmp_float & a, const gmp_float & b )
+{
+  gmp_float tmp( a );
+  tmp += b;
+  return tmp;
+}
+gmp_float operator - ( const gmp_float & a, const gmp_float & b )
+{
+  gmp_float tmp( a );
+  tmp -= b;
+  return tmp;
+}
+gmp_float operator * ( const gmp_float & a, const gmp_float & b )
+{
+  gmp_float tmp( a );
+  tmp *= b;
+  return tmp;
+}
+gmp_float operator / ( const gmp_float & a, const gmp_float & b )
+{
+  gmp_float tmp( a );
+  tmp /= b;
+  return tmp;
+}
+
+// <gmp_float> operator <gmp_float>
+gmp_float & gmp_float::operator += ( const gmp_float & a )
+{
+  if (mpf_sgn(t) != -(mpf_sgn(a.t)))
+  {
+    mpf_add( t, t, a.t);
+    return *this;
+  }
+  if((mpf_sgn(a.t)==0) && (mpf_sgn(t)==0))
+  {
+    mpf_set_d( t, 0.0);
+    return *this;
+  }
+  mpf_add( t, t, a.t );
+  mpf_set(diff.t, t);
+  mpf_set_prec(diff.t, 32);
+  mpf_div(diff.t, diff.t, a.t);
+  mpf_abs(diff.t, diff.t);
+  if(mpf_cmp(diff.t, gmpRel.t) < 0)
+    mpf_set_d( t, 0.0);
+  return *this;
+}
+gmp_float & gmp_float::operator -= ( const gmp_float & a )
+{
+  if (mpf_sgn(t) != mpf_sgn(a.t))
+  {
+    mpf_sub( t, t, a.t);
+    return *this;
+  }
+  if((mpf_sgn(a.t)==0) && (mpf_sgn(t)==0))
+  {
+    mpf_set_d( t, 0.0);
+    return *this;
+  }
+  mpf_sub( t, t, a.t );
+  mpf_set(diff.t, t);
+  mpf_set_prec(diff.t, 32);
+  mpf_div(diff.t, diff.t, a.t);
+  mpf_abs(diff.t, diff.t);
+  if(mpf_cmp(diff.t, gmpRel.t) < 0)
+    mpf_set_d( t, 0.0);
+  return *this;
+}
+
+// <gmp_float> == <gmp_float> ??
+bool operator == ( const gmp_float & a, const gmp_float & b )
+{
+  if(mpf_sgn(a.t) != mpf_sgn(b.t))
+    return false;
+  if((mpf_sgn(a.t)==0) && (mpf_sgn(b.t)==0))
+    return true;
+  mpf_sub(diff.t, a.t, b.t);
+  mpf_div(diff.t, diff.t, a.t);
+  mpf_abs(diff.t, diff.t);
+  if(mpf_cmp(diff.t, gmpRel.t) < 0)
+    return true;
+  else
+    return false;
+}
+// t == 0 ?
+bool gmp_float::isZero()
+{
+  return (mpf_sgn( t ) == 0);
+}
+// t == 1 ?
+bool gmp_float::isOne()
+{
+#ifdef  VARIANTE_1
+  return (mpf_cmp_ui( t , 1 ) == 0);
+#else
+  if (mpf_sgn(t) <= 0)
+    return false;
+  mpf_sub_ui(diff.t, t, 1);
+  mpf_abs(diff.t, diff.t);
+  if(mpf_cmp(diff.t, gmpRel.t) < 0)
+    return true;
+  else
+    return false;
+#endif
+}
+// t == -1 ?
+bool gmp_float::isMOne()
+{
+#ifdef VARIANTE_1
+  return (mpf_cmp_si( t , -1 ) == 0);
+#else
+  if (mpf_sgn(t) >= 0)
+    return false;
+  mpf_add_ui(diff.t, t, 1);
+  mpf_abs(diff.t, diff.t);
+  if(mpf_cmp(diff.t, gmpRel.t) < 0)
+    return true;
+  else
+    return false;
+#endif
+}
+bool operator > ( const gmp_float & a, const gmp_float & b )
+{
+  if (a.t == b.t)
+    return false;
+  return mpf_cmp( a.t, b.t ) > 0;
+}
+bool operator < ( const gmp_float & a, const gmp_float & b )
+{
+  if (a.t == b.t)
+    return false;
+  return mpf_cmp( a.t, b.t ) < 0;
+}
+bool operator >= ( const gmp_float & a, const gmp_float & b )
+{
+  if (a.t == b.t)
+    return true;
+  return mpf_cmp( a.t, b.t ) >= 0;
+}
+bool operator <= ( const gmp_float & a, const gmp_float & b )
+{
+  if (a.t == b.t)
+    return true;
+  return mpf_cmp( a.t, b.t ) <= 0;
+}
+
+// unary -
+gmp_float operator - ( const gmp_float & a )
+{
+  gmp_float tmp;
+  mpf_neg( *(tmp._mpfp()), *(a.mpfp()) );
+  return tmp;
+}
+
+gmp_float abs( const gmp_float & a )
+{
+  gmp_float tmp;
+  mpf_abs( *(tmp._mpfp()), *a.mpfp() );
+  return tmp;
+}
+gmp_float sqrt( const gmp_float & a )
+{
+  gmp_float tmp;
+  mpf_sqrt( *(tmp._mpfp()), *a.mpfp() );
+  return tmp;
+}
+gmp_float sin( const gmp_float & a )
+{
+  gmp_float tmp( sin((double)a) );
+  return tmp;
+}
+gmp_float cos( const gmp_float & a )
+{
+  gmp_float tmp( cos((double)a) );
+  return tmp;
+}
+gmp_float log( const gmp_float & a )
+{
+  gmp_float tmp( log((double)a) );
+  return tmp;
+}
+gmp_float hypot( const gmp_float & a, const gmp_float & b )
+{
+#if 1
+  return ( sqrt( (a*a) + (b*b) ) );
+#else
+  gmp_float tmp( hypot( (double)a, (double)b ) );
+  return tmp;
+#endif
+}
+gmp_float exp( const gmp_float & a )
+{
+  gmp_float tmp( exp((double)a) );
+  return tmp;
+}
+gmp_float max( const gmp_float & a, const gmp_float & b )
+{
+  gmp_float tmp;
+  a > b ? tmp= a : tmp= b;
+  return tmp;
+}
+//
+// number to float, number = Q, R, C
+// makes a COPY of num! (Ist das gut?)
+//
+gmp_float numberToFloat( number num )
+{
+  gmp_float r;
+
+  if ( rField_is_Q() )
+  {
+    if ( num != NULL )
+    {
+      if (SR_HDL(num) & SR_INT)
+      {
+        r= SR_TO_INT(num);
+      }
+      else
+      {
+        if ( num->s == 0 )
+        {
+          nlNormalize( num );
+        }
+        if (SR_HDL(num) & SR_INT)
+        {
+          r= SR_TO_INT(num);
+        }
+        else
+        {
+          if ( num->s != 3 )
+          {
+            r= &num->z;
+            r/= (gmp_float)&num->n;
+          }
+          else
+          {
+            r= &num->z;
+          }
+        }
+      }
+    }
+    else
+    {
+      r= 0.0;
+    }
+  }
+  else if (rField_is_long_R() || rField_is_long_C())
+  {
+    r= *(gmp_float*)num;
+  }
+  else if ( rField_is_R() )
+  {
+    // Add some code here :-)
+    WerrorS("Ground field not implemented!");
+  }
+  else
+  {
+    WerrorS("Ground field not implemented!");
+  }
+
+  return r;
+}
+
+gmp_float numberFieldToFloat( number num, int k )
+{
+  gmp_float r;
+
+  switch (k)
+  {
+  case QTOF:
+    if ( num != NULL )
+    {
+      if (SR_HDL(num) & SR_INT)
+      {
+        r= SR_TO_INT(num);
+      }
+      else
+      {
+        if ( num->s == 0 )
+        {
+          nlNormalize( num );
+        }
+        if (SR_HDL(num) & SR_INT)
+        {
+          r= SR_TO_INT(num);
+        }
+        else
+        {
+          if ( num->s != 3 )
+          {
+            r= &num->z;
+            r/= (gmp_float)&num->n;
+          }
+          else
+          {
+            r= &num->z;
+          }
+        }
+      }
+    }
+    else
+    {
+      r= 0.0;
+    }
+    break;
+  case RTOF:
+    r= *(gmp_float*)num;
+    break;
+  case CTOF:
+    WerrorS("Can not map from field C to field R!");
+    break;
+  case ZTOF:
+  default:
+    WerrorS("Ground field not implemented!");
+  } // switch
+
+  return r;
+}
+
+// Do some strange things with the mantissa string and the exponent
+// to get some nice output string.
+char *nicifyFloatStr( char * in, mp_exp_t exponent, size_t oprec, int *size, int thesign )
+{
+  char *out;
+
+  int sign= (in[0] == '-') ? 1 : 0;
+  char csign[2];
+
+  switch (thesign)
+  {
+    case SIGN_PLUS:
+      sign ? strcpy(csign,"-") : strcpy(csign,"+");  //+123, -123
+      break;
+    case SIGN_SPACE:
+      sign ? strcpy(csign,"-") : strcpy(csign," ");  // 123, -123
+      break;
+    case SIGN_EMPTY:
+    default:
+      sign ? strcpy(csign,"-") : strcpy(csign,"");   //123, -123
+      break;
+  }
+
+  if ( strlen(in) == 0 )
+  {
+    *size= 2*sizeof(char);
+    return omStrDup("0");
+  }
+
+  if ( ((unsigned int)ABS(exponent) <= oprec)
+       /*|| (exponent+sign >= (int)strlen(in))*/ )
+  {
+    if ( exponent+sign < (int)strlen(in) )
+    {
+      int eexponent= (exponent >= 0) ? 0 : -exponent;
+      int eeexponent= (exponent >= 0) ? exponent : 0;
+      *size= (strlen(in)+15+eexponent) * sizeof(char);
+      out= (char*)omAlloc(*size);
+      memset(out,0,*size);
+
+      strcpy(out,csign);
+      strncat(out,in+sign,eeexponent);
+
+      if (exponent == 0)
+        strcat(out,"0.");
+      else if ( exponent > 0 )
+        strcat(out,".");
+      else
+      {
+        strcat(out,"0.");
+        memset(out+strlen(out),'0',eexponent);
+      }
+      strcat(out,in+sign+eeexponent);
+    }
+    else if ( exponent+sign > (int)strlen(in) )
+    {
+      *size= (strlen(in)+exponent+12)*sizeof(char);
+      out= (char*)omAlloc(*size);
+      memset(out,0,*size);
+      sprintf(out,"%s%s",csign,in+sign);
+      memset(out+strlen(out),'0',exponent-strlen(in)+sign);
+    }
+    else
+    {
+      *size= (strlen(in)+2) * sizeof(char) + 10;
+      out= (char*)omAlloc(*size);
+      memset(out,0,*size);
+      sprintf(out,"%s%s",csign,in+sign);
+    }
+  }
+  else
+  {
+//      if ( exponent > 0 )
+//      {
+      int c=1,d=10;
+      while ( exponent / d > 0 )
+      { // count digits
+        d*=10;
+        c++;
+      }
+      *size= (strlen(in)+12+c) * sizeof(char) + 10;
+      out= (char*)omAlloc(*size);
+      memset(out,0,*size);
+      sprintf(out,"%s0.%se%s%d",csign,in+sign,exponent>=0?"+":"",(int)exponent);
+//      }
+//      else
+//      {
+//        *size=2;
+//        out= (char*)omAlloc(*size);
+//        strcpy(out,"0");
+//      }
+  }
+  return out;
+}
+
+char *floatToStr( const gmp_float & r, const unsigned int oprec )
+{
+#if 1
+  mp_exp_t exponent;
+  int size,insize;
+  char *nout,*out,*in;
+
+  insize= (oprec+2) * sizeof(char) + 10;
+  in= (char*)omAlloc( insize );
+
+  mpf_get_str(in,&exponent,10,oprec,*(r.mpfp()));
+
+  if ( (exponent > 0)
+  && (exponent < (int)oprec)
+  && (strlen(in)-(in[0]=='-'?1:0) == oprec) )
+  {
+    omFree( (ADDRESS) in );
+    insize= (exponent+oprec+2) * sizeof(char) + 10;
+    in= (char*)omAlloc( insize );
+    int newprec= exponent+oprec;
+    mpf_get_str(in,&exponent,10,newprec,*(r.mpfp()));
+  }
+  nout= nicifyFloatStr( in, exponent, oprec, &size, SIGN_EMPTY );
+  omFree( (ADDRESS) in );
+  out= (char*)omAlloc( (strlen(nout)+1) * sizeof(char) );
+  strcpy( out, nout );
+  omFree( (ADDRESS) nout );
+
+  return out;
+#else
+  // for testing purpose...
+  char *out= (char*)omAlloc( (1024) * sizeof(char) );
+  sprintf(out,"% .10f",(double)r);
+  return out;
+#endif
+}
+//<-
+
+//-> gmp_complex::*
+// <gmp_complex> = <gmp_complex> operator <gmp_complex>
+//
+gmp_complex operator + ( const gmp_complex & a, const gmp_complex & b )
+{
+  return gmp_complex( a.r + b.r, a.i + b.i );
+}
+gmp_complex operator - ( const gmp_complex & a, const gmp_complex & b )
+{
+  return gmp_complex( a.r - b.r, a.i - b.i );
+}
+gmp_complex operator * ( const gmp_complex & a, const gmp_complex & b )
+{
+  return gmp_complex( a.r * b.r - a.i * b.i,
+                  a.r * b.i + a.i * b.r);
+}
+gmp_complex operator / ( const gmp_complex & a, const gmp_complex & b )
+{
+  gmp_float d = b.r*b.r + b.i*b.i;
+  return gmp_complex( (a.r * b.r + a.i * b.i) / d,
+                (a.i * b.r - a.r * b.i) / d);
+}
+
+// <gmp_complex> operator <gmp_complex>
+//
+gmp_complex & gmp_complex::operator += ( const gmp_complex & b )
+{
+  r+=b.r;
+  i+=b.i;
+  return *this;
+}
+gmp_complex & gmp_complex::operator -= ( const gmp_complex & b )
+{
+  r-=b.r;
+  i-=b.i;
+  return *this;
+}
+gmp_complex & gmp_complex::operator *= ( const gmp_complex & b )
+{
+  gmp_float f = r * b.r - i * b.i;
+  i = r * b.i + i * b.r;
+  r = f;
+  return *this;
+}
+gmp_complex & gmp_complex::operator /= ( const gmp_complex & b )
+{
+  gmp_float d = b.r*b.r + b.i*b.i;
+  r = (r * b.r + i * b.i) / d;
+  i = (i * b.r - r * b.i) / d;
+  return *this;
+}
+
+// Returns square root of gmp_complex number
+//
+gmp_complex sqrt( const gmp_complex & x )
+{
+  gmp_float r = abs(x);
+  gmp_float nr, ni;
+  if (r == (gmp_float) 0.0)
+  {
+    nr = ni = r;
+  }
+  else if ( x.real() > (gmp_float)0)
+  {
+    nr = sqrt((gmp_float)0.5 * (r + x.real()));
+    ni = x.imag() / nr / (gmp_float)2;
+  }
+  else
+  {
+    ni = sqrt((gmp_float)0.5 * (r - x.real()));
+    if (x.imag() < (gmp_float)0)
+    {
+      ni = - ni;
+    }
+    nr = x.imag() / ni / (gmp_float)2;
+  }
+  gmp_complex *tmp= new gmp_complex(nr, ni);
+  return *tmp;
+}
+
+// converts a gmp_complex to a string ( <real part> + I * <imaginary part> )
+//
+char *complexToStr( gmp_complex & c, const unsigned int oprec )
+{
+  char *out,*in_imag,*in_real;
+
+  c.SmallToZero();
+  if ( !c.imag().isZero() )
+  {
+
+    in_real=floatToStr( c.real(), oprec );         // get real part
+    in_imag=floatToStr( abs(c.imag()), oprec );    // get imaginary part
+
+    if (rField_is_long_C())
+    {
+      int len=(strlen(in_real)+strlen(in_imag)+7+strlen(currRing->parameter[0]))*sizeof(char);
+      out=(char*)omAlloc(len);
+      memset(out,0,len);
+      if (  !c.real().isZero() )  // (-23-i*5.43) or (15.1+i*5.3)
+        sprintf(out,"(%s%s%s*%s)",in_real,c.imag().sign()>=0?"+":"-",currRing->parameter[0],in_imag);
+      else // (-i*43) or (i*34)
+      {
+        if (c.imag().isOne())
+          sprintf(out,currRing->parameter[0]);
+        else if (c.imag().isMOne())
+          sprintf(out,"-%s",currRing->parameter[0]);
+        else
+          sprintf(out,"(%s%s*%s)",c.imag().sign()>=0?"":"-",currRing->parameter[0],in_imag);
+      }
+    }
+    else
+    {
+      int len=(strlen(in_real)+strlen(in_imag)+9) * sizeof(char);
+      out=(char*)omAlloc( len );
+      memset(out,0,len);
+      if ( !c.real().isZero() )
+        sprintf(out,"(%s%s%s)",in_real,c.imag().sign()>=0?"+I*":"-I*",in_imag);
+      else
+        sprintf(out,"(%s%s)",c.imag().sign()>=0?"I*":"-I*",in_imag);
+    }
+    omFree( (ADDRESS) in_real );
+    omFree( (ADDRESS) in_imag );
+  }
+  else
+  {
+    out= floatToStr( c.real(), oprec );
+  }
+
+  return out;
+}
+//<-
+
+bool complexNearZero( gmp_complex * c, int digits )
+{
+  gmp_float eps,epsm;
+
+  if ( digits < 1 ) return true;
+
+  eps=pow(10.0,(int)digits);
+  //Print("eps: %s\n",floatToStr(eps,gmp_output_digits));
+  eps=(gmp_float)1.0/eps;
+  epsm=-eps;
+
+  //Print("eps: %s\n",floatToStr(eps,gmp_output_digits));
+
+  if ( c->real().sign() > 0 ) // +
+    return (c->real() < eps && (c->imag() < eps && c->imag() > epsm));
+  else // -
+    return (c->real() > epsm && (c->imag() < eps && c->imag() > epsm));
+}
+
+void gmp_complex::SmallToZero()
+{
+  gmp_float ar=this->real();
+  gmp_float ai=this->imag();
+  if (ar.isZero() || ai.isZero()) return;
+  mpf_abs(*ar._mpfp(), *ar._mpfp());
+  mpf_abs(*ai._mpfp(), *ai._mpfp());
+  mpf_set_prec(*ar._mpfp(), 32);
+  mpf_set_prec(*ai._mpfp(), 32);
+  if (ar > ai)
+  {
+    mpf_div(*ai._mpfp(), *ai._mpfp(), *ar._mpfp());
+    if (ai < gmpRel) this->imag(0.0);
+  }
+  else
+  {
+    mpf_div(*ar._mpfp(), *ar._mpfp(), *ai._mpfp());
+    if (ar < gmpRel) this->real(0.0);
+  }
+}
+
+//%e
+
+//#endif // HAVE_MPR
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-1: "make installg" ***
+// compile-command-2: "make install" ***
+// End: ***
Index: kernel/mpr_complex.h
===================================================================
--- kernel/mpr_complex.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/mpr_complex.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,334 @@
+#ifndef MPR_COMPLEX_H
+#define MPR_COMPLEX_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: mpr_complex.h,v 1.1.1.1 2003-10-06 12:15:58 Singular Exp $ */
+
+/*
+* ABSTRACT - multipolynomial resultants - real floating-point numbers using gmp
+*            and complex numbers based on pairs of real floating-point numbers
+*
+*/
+
+//-> include & define stuff
+// must have gmp version >= 2
+#include "si_gmp.h"
+#include "numbers.h"
+#include "ring.h"
+#include "mpr_global.h"
+
+#define ZTOF 1
+#define QTOF 2
+#define RTOF 3
+#define CTOF 4
+
+void setGMPFloatDigits( size_t digits, size_t rest );
+size_t getGMPFloatDigits();
+
+//-> class gmp_float
+/**
+ * @short wrapper class for GNU Multi Precision Floats
+ */
+class gmp_float
+{
+public:
+  gmp_float( const int v = 0 )
+  {
+    mpf_init_set_d( t, (double) v );
+  }
+  gmp_float( const long v )
+  {
+    mpf_init_set_d( t, (double) v );
+  }
+  gmp_float( const mprfloat v ) // double
+  {
+    mpf_init_set_d( t, (double) v );
+  }
+  gmp_float( const mpf_t v )
+  {
+    mpf_init_set( t, v );
+  }
+  gmp_float( const mpz_t v ) // gnu mp Z
+  {
+    mpf_init( t );
+    mpf_set_z( t, v );
+  }
+  gmp_float( const gmp_float & v ) // copy constructor
+  {
+    mpf_init_set( t, v.t );
+  }
+
+  ~gmp_float()
+  {
+    mpf_clear( t );
+  }
+
+  friend gmp_float operator + ( const gmp_float & a, const gmp_float & b );
+  friend gmp_float operator - ( const gmp_float & a, const gmp_float & b );
+  friend gmp_float operator * ( const gmp_float & a, const gmp_float & b );
+  friend gmp_float operator / ( const gmp_float & a, const gmp_float & b );
+
+  gmp_float & operator += ( const gmp_float & a );
+  gmp_float & operator -= ( const gmp_float & a );
+  inline gmp_float & operator *= ( const gmp_float & a );
+  inline gmp_float & operator /= ( const gmp_float & a );
+
+  friend bool operator == ( const gmp_float & a, const gmp_float & b );
+  friend bool operator  > ( const gmp_float & a, const gmp_float & b );
+  friend bool operator  < ( const gmp_float & a, const gmp_float & b );
+  friend bool operator >= ( const gmp_float & a, const gmp_float & b );
+  friend bool operator <= ( const gmp_float & a, const gmp_float & b );
+
+  friend gmp_float operator - ( const gmp_float & a );
+
+  gmp_float & operator = ( const gmp_float & a );
+  gmp_float & operator = ( const mpz_t & a );
+  gmp_float & operator = ( const mprfloat a );
+  gmp_float & operator = ( const long a );
+
+  inline int sign();    // t>0:+1, t==0:0, t<0:-1
+  bool isZero();  // t == 0 ?
+  bool isOne();   // t == 1 ?
+  bool isMOne();  // t == -1 ?
+
+  void setFromStr( char * in );
+
+  // access
+  inline const mpf_t *mpfp() const;
+  inline mpf_t *_mpfp();
+  
+  inline operator double();
+  inline operator double() const;
+
+  inline operator int();
+  inline operator int() const;
+
+private:
+  mpf_t t;
+};
+
+// <gmp_float> operator <gmp_float>
+inline gmp_float & gmp_float::operator *= ( const gmp_float & a )
+{
+  mpf_mul( t, t, a.t );
+  return *this;
+}
+inline gmp_float & gmp_float::operator /= ( const gmp_float & a )
+{
+  mpf_div( t, t, a.t );
+  return *this;
+}
+
+// <gmp_float> = <*>
+inline gmp_float & gmp_float::operator = ( const gmp_float & a )
+{
+  mpf_set( t, a.t );
+  return *this;
+}
+inline gmp_float & gmp_float::operator = ( const mpz_t & a )
+{
+  mpf_set_z( t, a );
+  return *this;
+}
+inline gmp_float & gmp_float::operator = ( const mprfloat a )
+{
+  mpf_set_d( t, (double) a );
+  return *this;
+}
+inline gmp_float & gmp_float::operator = ( const long a )
+{
+  mpf_set_d( t, (double) a );
+  return *this;
+}
+
+// cast to double
+inline gmp_float::operator double()
+{
+  return mpf_get_d( t );
+}
+inline gmp_float::operator double() const
+{
+  return mpf_get_d( t );
+}
+
+// cast to int
+inline gmp_float::operator int()
+{
+  return (int)mpf_get_d( t );
+}
+inline gmp_float::operator int() const
+{
+  return (int)mpf_get_d( t );
+}
+
+// get sign of real number ( -1: t < 0; 0: t==0; 1: t > 0 )
+inline int gmp_float::sign()
+{
+  return mpf_sgn( t );
+}
+
+// access pointer
+inline const mpf_t *gmp_float::mpfp() const
+{
+  return &t;
+}
+
+inline mpf_t *gmp_float::_mpfp() 
+{
+  return &t;
+}
+
+// built-in functions of GMP
+gmp_float abs( const gmp_float & );
+gmp_float sqrt( const gmp_float & );
+gmp_float hypot( const gmp_float &, const gmp_float & );
+//gmp_float pow( const gmp_float &, int & );
+
+// simulated functions using double functions
+gmp_float sin( const gmp_float & );
+gmp_float cos( const gmp_float & );
+gmp_float log( const gmp_float & );
+gmp_float exp( const gmp_float & );
+
+gmp_float max( const gmp_float &, const gmp_float & );
+
+gmp_float numberToFloat( number num );
+gmp_float numberFieldToFloat( number num, int k );
+char *floatToStr( const gmp_float & r, const unsigned int oprec );
+//<-
+
+//-> class gmp_complex
+/**
+ * @short gmp_complex numbers based on
+ */
+class gmp_complex
+{
+private:
+  gmp_float r, i;
+
+public:
+  gmp_complex( const gmp_float re= 0.0, const gmp_float im= 0.0 )
+  {
+    r= re;
+    i= im;
+  }
+  gmp_complex( const mprfloat re, const mprfloat im = 0.0 )
+  {
+    r= re;
+    i= im;
+  }
+  gmp_complex( const long re, const long im )
+  {
+    r= re;
+    i= im;
+  }
+  gmp_complex( const gmp_complex & v )
+  {
+    r= v.r;
+    i= v.i;
+  }
+  ~gmp_complex() {}
+
+  friend gmp_complex operator + ( const gmp_complex & a, const gmp_complex & b );
+  friend gmp_complex operator - ( const gmp_complex & a, const gmp_complex & b );
+  friend gmp_complex operator * ( const gmp_complex & a, const gmp_complex & b );
+  friend gmp_complex operator / ( const gmp_complex & a, const gmp_complex & b );
+
+  // gmp_complex <operator> real
+  inline friend gmp_complex operator + ( const gmp_complex & a, const gmp_float b_d );
+  inline friend gmp_complex operator - ( const gmp_complex & a, const gmp_float b_d );
+  inline friend gmp_complex operator * ( const gmp_complex & a, const gmp_float b_d );
+  inline friend gmp_complex operator / ( const gmp_complex & a, const gmp_float b_d );
+
+  gmp_complex & operator += ( const gmp_complex & a );
+  gmp_complex & operator -= ( const gmp_complex & a );
+  gmp_complex & operator *= ( const gmp_complex & a );
+  gmp_complex & operator /= ( const gmp_complex & a );
+
+  inline friend bool operator == ( const gmp_complex & a, const gmp_complex & b );
+
+  inline gmp_complex & operator = ( const gmp_complex & a );
+  inline gmp_complex & operator = ( const gmp_float & f );
+
+  // access to real and imaginary part
+  inline gmp_float real() const { return r; }
+  inline gmp_float imag() const { return i; }
+
+  inline void real( gmp_float val ) { r = val; }
+  inline void imag( gmp_float val ) { i = val; }
+
+  void SmallToZero();
+};
+
+// <gmp_complex> = <gmp_complex> operator <gmp_float>
+//
+inline gmp_complex operator + ( const gmp_complex & a, const gmp_float b_d )
+{
+  return gmp_complex( a.r + b_d, a.i );
+}
+inline gmp_complex operator - ( const gmp_complex & a, const gmp_float b_d )
+{
+  return gmp_complex( a.r - b_d, a.i );
+}
+inline gmp_complex operator * ( const gmp_complex & a, const gmp_float b_d )
+{
+  return gmp_complex( a.r * b_d, a.i * b_d );
+}
+inline gmp_complex operator / ( const gmp_complex & a, const gmp_float b_d )
+{
+  return gmp_complex( a.r / b_d, a.i / b_d );
+}
+
+// <gmp_complex> == <gmp_complex> ?
+inline bool operator == ( const gmp_complex & a, const gmp_complex & b )
+{
+  return ( b.real() == a.real() ) && ( b.imag() == a.imag() );
+}
+
+// <gmp_complex> = <gmp_complex>
+inline gmp_complex & gmp_complex::operator = ( const gmp_complex & a )
+{
+  r= a.r;
+  i= a.i;
+  return *this;
+}
+
+// <gmp_complex> = <gmp_complex>
+inline gmp_complex & gmp_complex::operator = ( const gmp_float & f )
+{
+  r= f;
+  i= (long int)0;
+  return *this;
+}
+
+// Returns absolute value of a gmp_complex number
+//
+inline gmp_float abs( const gmp_complex & c )
+{
+  return hypot(c.real(),c.imag());
+}
+
+gmp_complex sqrt( const gmp_complex & x );
+
+inline gmp_complex numberToComplex( number num )
+{
+  if (rField_is_long_C()) {
+    return *(gmp_complex*)num;
+  } else {
+    return gmp_complex( numberToFloat(num) );
+  }
+}
+
+char *complexToStr( gmp_complex & c, const  unsigned int oprec );
+//<-
+
+bool complexNearZero( gmp_complex * c, int digits );
+
+#endif /* MPR_COMPLEX_H */
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-1: "make installg" ***
+// compile-command-2: "make install" ***
+// End: ***
Index: kernel/mpr_global.h
===================================================================
--- kernel/mpr_global.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/mpr_global.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,95 @@
+#ifndef MPR_GLOBAL_H
+#define MPR_GLOBAL_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: mpr_global.h,v 1.1.1.1 2003-10-06 12:15:58 Singular Exp $ */
+
+/*
+* ABSTRACT - multipolynomial resultants -
+*                                global definitions and debugging stuff
+*/
+
+// to get detailed timigs, define MPR_TIMING
+//#define MPR_TIMING
+
+// Set to double or long double. double is recomended.
+// Sets the global floating point type used in mpr_numeric.cc.
+typedef double mprfloat;
+
+// --------------------------- debugging stuff ----------------------------
+#if !defined(NDEBUG)
+//#define mprDEBUG_ALL
+#endif
+
+#if !defined(NDEBUG) || defined(mprDEBUG_ALL)
+#define mprDEBUG_PROT
+#endif
+
+#if !defined(NDEBUG) && !defined(MPR_TIMING)
+#define MPR_TIMING
+#endif
+
+#define mprDEBUG_STICKY
+
+#ifdef mprDEBUG_PROT
+#define mprPROT(msg) PrintS(msg)
+#define mprPROTnl(msg) Print("%s\n",msg)
+#define mprPROTP(msg,poly) PrintS(msg);pWrite0(poly)
+#define mprPROTPnl(msg,poly) PrintS(msg);pWrite(poly)
+#define mprPROTI(msg,intval) Print("%s%d",msg,intval)
+#define mprPROTInl(msg,intval) Print("%s%d\n",msg,intval)
+#define mprPROTN(msg,nval) PrintS(msg);nPrint(nval);
+#define mprPROTNnl(msg,nval) PrintS(msg);nPrint(nval);PrintLn();
+#else
+#define mprPROT(msg)
+#define mprPROTnl(msg)
+#define mprPROTP(msg,poly)
+#define mprPROTPnl(msg,poly)
+#define mprPROTI(msg,intval)
+#define mprPROTInl(msg,intval)
+#define mprPROTN(msg,nval)
+#define mprPROTNnl(msg,nval)
+#endif
+
+#if defined(mprDEBUG_STICKY) && defined(HAVE_FACTORY)
+// call 'option(prot);' to get status informations
+#define mprSTICKYPROT(msg) if (BTEST1(OPT_PROT)) Print(msg)
+#define mprSTICKYPROT2(msg,arg) if (BTEST1(OPT_PROT)) Print(msg,arg)
+#else
+#define mprSTICKYPROT(msg)
+#define mprSTICKYPROT2(msg,arg)
+#endif
+
+// output by mprSTICKYPROT
+#define ST_BASE_EV "."
+
+#define ST_DENSE_FR ":"
+#define ST_DENSE_NR "."
+#define ST_DENSE_MEM "+"
+#define ST_DENSE_NMON "-"
+
+#define ST_SPARSE_MEM "+"
+#define ST_SPARSE_VADD "+"
+#define ST_SPARSE_VREJ "-"
+#define ST_SPARSE_MPEND "e"
+#define ST_SPARSE_MREC1 "r"
+#define ST_SPARSE_MREC2 "R"
+#define ST_SPARSE_RC "+"
+#define ST_SPARSE_RCRJ "-"
+
+#define ST__DET "|"
+
+#define ST_ROOTS_LGSTEP "|"
+#define ST_ROOTS_LGPOLISH "#"
+#define ST_ROOTS_LG "-"
+
+#define ST_VANDER_STEP "."
+
+#endif
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-1: "make installg" ***
+// compile-command-2: "make install" ***
+// End: ***
Index: kernel/mpr_inout.cc
===================================================================
--- kernel/mpr_inout.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/mpr_inout.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,217 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/* $Id: mpr_inout.cc,v 1.1.1.1 2003-10-06 12:15:56 Singular Exp $ */
+
+/*
+* ABSTRACT - multipolynomial resultant
+*/
+
+#include "mod2.h"
+//#ifdef HAVE_MPR
+
+//-> includes
+#include "structs.h"
+#include "polys.h"
+#include "ideals.h"
+#include "ring.h"
+#include "febase.h"
+#include "omalloc.h"
+#include "numbers.h"
+#include "matpol.h"
+
+#include <math.h>
+
+#include "mpr_global.h"
+#include "mpr_inout.h"
+#include "mpr_base.h"
+#include "mpr_numeric.h"
+
+// to get detailed timigs, define MPR_TIMING
+#ifdef MPR_TIMING
+#define TIMING
+#endif
+#include "../factory/timing.h"
+TIMING_DEFINE_PRINT(mpr_overall)
+TIMING_DEFINE_PRINT(mpr_check)
+TIMING_DEFINE_PRINT(mpr_constr)
+TIMING_DEFINE_PRINT(mpr_ures)
+TIMING_DEFINE_PRINT(mpr_mures)
+TIMING_DEFINE_PRINT(mpr_arrange)
+TIMING_DEFINE_PRINT(mpr_solver)
+
+#define TIMING_EPR(t,msg) TIMING_END_AND_PRINT(t,msg);TIMING_RESET(t);
+
+extern size_t gmp_output_digits;
+//<-
+
+//-> nPrint(number n)
+void nPrint(number n)
+{
+  poly o=pOne();
+  pSetCoeff(o, nCopy(n) );
+  pWrite0( o );
+  pDelete( &o );
+}
+//<-
+
+//------------------------------------------------------------------------------
+
+//-> void mprPrintError( mprState state )
+void mprPrintError( mprState state, const char * name )
+{
+  switch (state)
+  {
+  case mprWrongRType:
+    WerrorS("Unknown resultant matrix type choosen!");
+    break;
+  case mprHasOne:
+    Werror("One element of the ideal %s is constant!",name);
+    break;
+  case mprInfNumOfVars:
+    Werror("Numer of elements in given ideal %s must be equal to %d!",
+           name,pVariables+1);
+    break;
+  case mprNotZeroDim:
+    Werror("The given ideal %s must 0-dimensional!",name);
+    break;
+  case mprNotHomog:
+    Werror("The given ideal %s has to be homogeneous in"
+           " the first ring variable!",name);
+    break;
+  case mprNotReduced:
+    Werror("The given ideal %s has to reduced!",name);
+    break;
+  case mprUnSupField:
+    WerrorS("Ground field not implemented!");
+    break;
+  default:
+    break;
+  }
+}
+//<-
+
+//-> mprState mprIdealCheck()
+mprState mprIdealCheck( const ideal theIdeal,
+                        const char * name,
+                        uResultant::resMatType mtype,
+                        BOOLEAN rmatrix= false )
+{
+  mprState state = mprOk;
+  int power;
+  int k;
+
+  int numOfVars= mtype == uResultant::denseResMat?pVariables-1:pVariables;
+  if ( rmatrix ) numOfVars++;
+
+  if ( mtype == uResultant::none )
+    state= mprWrongRType;
+
+  if ( IDELEMS(theIdeal) != numOfVars )
+    state= mprInfNumOfVars;
+
+  for ( k= IDELEMS(theIdeal) - 1; (state == mprOk) && (k >= 0); k-- )
+  {
+    poly p = (theIdeal->m)[k];
+    if ( pIsConstant(p) ) state= mprHasOne;
+    else
+    if ( (mtype == uResultant::denseResMat) && !pIsHomogeneous(p) )
+      state=mprNotHomog;
+  }
+
+  if ( !(rField_is_R()||
+         rField_is_Q()||
+         rField_is_long_R()||
+         rField_is_long_C()||
+         (rmatrix && rField_is_Q_a())) )
+    state= mprUnSupField;
+
+  if ( state != mprOk ) mprPrintError( state, "" /* name */ );
+
+  return state;
+}
+//<-
+
+//-> uResultant::resMatType determineMType( int imtype )
+uResultant::resMatType determineMType( int imtype )
+{
+  switch ( imtype )
+  {
+  case MPR_DENSE:
+    return uResultant::denseResMat;
+  case 0:
+  case MPR_SPARSE:
+    return uResultant::sparseResMat;
+  default:
+    return uResultant::none;
+  }
+}
+//<-
+
+//-> function u_resultant_det
+poly u_resultant_det( ideal gls, int imtype )
+{
+  uResultant::resMatType mtype= determineMType( imtype );
+  poly resdet;
+  poly emptypoly= pInit();
+  number smv= NULL;
+
+  TIMING_START(mpr_overall);
+
+  // check input ideal ( = polynomial system )
+  if ( mprIdealCheck( gls, "", mtype ) != mprOk )
+  {
+    return emptypoly;
+  }
+
+  uResultant *ures;
+
+  // main task 1: setup of resultant matrix
+  TIMING_START(mpr_constr);
+  ures= new uResultant( gls, mtype );
+  TIMING_EPR(mpr_constr,"construction");
+
+  // if dense resultant, check if minor nonsingular
+  if ( mtype == uResultant::denseResMat )
+  {
+    smv= ures->accessResMat()->getSubDet();
+#ifdef mprDEBUG_PROT
+    PrintS("// Determinant of submatrix: ");nPrint(smv); PrintLn();
+#endif
+    if ( nIsZero(smv) )
+    {
+      WerrorS("Unsuitable input ideal: Minor of resultant matrix is singular!");
+      return emptypoly;
+    }
+  }
+
+  // main task 2: Interpolate resultant polynomial
+  TIMING_START(mpr_ures);
+  resdet= ures->interpolateDense( smv );
+  TIMING_EPR(mpr_ures,"ures");
+
+  // free mem
+  delete ures;
+  nDelete( &smv );
+  pDelete( &emptypoly );
+
+  TIMING_EPR(mpr_overall,"overall");
+
+  return ( resdet );
+}
+//<-
+
+//-----------------------------------------------------------------------------
+
+//#endif // HAVE_MPR
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-1: "make installg" ***
+// compile-command-2: "make install" ***
+// End: ***
+
+// in folding: C-c x
+// leave fold: C-c y
+//   foldmode: F10
Index: kernel/mpr_inout.h
===================================================================
--- kernel/mpr_inout.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/mpr_inout.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,75 @@
+#ifndef MPR_H
+#define MPR_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/* $Id: mpr_inout.h,v 1.1.1.1 2003-10-06 12:15:58 Singular Exp $ */
+
+/*
+* ABSTRACT - multipolynomial resultants - interface to Singular
+*
+*/
+
+#define DEFAULT_DIGITS 30
+
+#define MPR_DENSE  1
+#define MPR_SPARSE 2
+
+/** solve a multipolynomial system using the u-resultant
+ * Input ideal must be 0-dimensional and pVariables == IDELEMS(ideal).
+ * Resultant method can be MPR_DENSE, which uses Macaulay Resultant (good for
+ * dense homogeneous polynoms) or MPR_SPARSE, which uses Sparse Resultant
+ * (Gelfand, Kapranov, Zelevinsky).
+ * Arguments 4: ideal i, int k, int l, int m
+ *   k=0: use sparse resultant matrix of Gelfand, Kapranov and Zelevinsky
+ *   k=1: use resultant matrix of Macaulay (k=0 is default)
+ *   l>0: defines precision of fractional part if ground field is Q
+ *   m=0,1,2: number of iterations for approximation of roots (default=2)
+ * Returns a list containing the roots of the system.
+ */
+BOOLEAN nuUResSolve( leftv res, leftv args );
+
+/** returns module representing the multipolynomial resultant matrix
+ * Arguments 2: ideal i, int k
+ *   k=0: use sparse resultant matrix of Gelfand, Kapranov and Zelevinsky
+ *   k=1: use resultant matrix of Macaulay (k=0 is default)
+ */
+BOOLEAN nuMPResMat( leftv res, leftv arg1, leftv arg2 );
+
+/** find the (complex) roots an univariate polynomial
+ * Determines the roots of an univariate polynomial using Laguerres'
+ * root-solver. Good for polynomials with low and middle degree (<40).
+ * Arguments 3: poly arg1 , int arg2 , int arg3
+ *  arg2>0: defines precision of fractional part if ground field is Q
+ *  arg3: number of iterations for approximation of roots (default=2)
+ * Returns a list of all (complex) roots of the polynomial arg1
+ */
+BOOLEAN nuLagSolve( leftv res, leftv arg1, leftv arg2, leftv arg3 );
+
+/**
+ * COMPUTE: polynomial p with values given by v at points p1,..,pN derived
+ * from p; more precisely: consider p as point in K^n and v as N elements in K,
+ * let p1,..,pN be the points in K^n obtained by evaluating all monomials
+ * of degree 0,1,...,N at p in lexicographical order, then the procedure
+ * computes the polynomial f satisfying f(pi) = v[i]
+ * RETURN:  polynomial f of degree d
+ */
+BOOLEAN nuVanderSys( leftv res, leftv arg1, leftv arg2, leftv arg3 );
+
+/** compute Newton Polytopes of input polynomials
+ */
+BOOLEAN loNewtonP( leftv res, leftv arg1 );
+
+/** Implementation of the Simplex Algorithm.
+ * For args, see class simplex.
+ */
+BOOLEAN loSimplex( leftv res, leftv args );
+
+#endif
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-1: "make installg" ***
+// compile-command-2: "make install" ***
+// End: ***
Index: kernel/mpr_numeric.cc
===================================================================
--- kernel/mpr_numeric.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/mpr_numeric.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1357 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/* $Id: mpr_numeric.cc,v 1.1.1.1 2003-10-06 12:15:56 Singular Exp $ */
+
+/*
+* ABSTRACT - multipolynomial resultants - numeric stuff
+*            ( root finder, vandermonde system solver, simplex )
+*/
+
+#include "mod2.h"
+//#ifdef HAVE_MPR
+
+//#define mprDEBUG_ALL
+
+//-> includes
+#include "structs.h"
+#include "febase.h"
+#include "omalloc.h"
+#include "numbers.h"
+#include "polys.h"
+#include "ideals.h"
+#include "intvec.h"
+#include "matpol.h"
+#include "ring.h"
+//#include "longrat.h"
+
+#include <math.h>
+#include "mpr_numeric.h"
+
+extern size_t gmp_output_digits;
+//<-
+
+extern void nPrint(number n);  // for debugging output
+
+//-----------------------------------------------------------------------------
+//-------------- vandermonde system solver ------------------------------------
+//-----------------------------------------------------------------------------
+
+//-> vandermonde::*
+vandermonde::vandermonde( const long _cn, const long _n, const long _maxdeg,
+                          number *_p, const bool _homog )
+  : n(_n), cn(_cn), maxdeg(_maxdeg), p(_p), homog(_homog)
+{
+  long j;
+  l= (long)pow((double)maxdeg+1,(int)n);
+  x= (number *)omAlloc( cn * sizeof(number) );
+  for ( j= 0; j < cn; j++ ) x[j]= nInit(1);
+  init();
+}
+
+vandermonde::~vandermonde()
+{
+  int j;
+  for ( j= 0; j < cn; j++ ) nDelete( x+j );
+  omFreeSize( (ADDRESS)x, cn * sizeof( number ) );
+}
+
+void vandermonde::init()
+{
+  int j;
+  long i,c,sum;
+  number tmp,tmp1;
+
+  c=0;
+  sum=0;
+
+  intvec exp( n );
+  for ( j= 0; j < n; j++ ) exp[j]=0;
+
+  for ( i= 0; i < l; i++ )
+  {
+    if ( !homog || (sum == maxdeg) )
+    {
+      for ( j= 0; j < n; j++ )
+      {
+        nPower( p[j], exp[j], &tmp );
+        tmp1 = nMult( tmp, x[c] );
+        x[c]= tmp1;
+        nDelete( &tmp );
+      }
+      c++;
+    }
+    exp[0]++;
+    sum=0;
+    for ( j= 0; j < n - 1; j++ )
+    {
+      if ( exp[j] > maxdeg )
+      {
+        exp[j]= 0;
+        exp[j + 1]++;
+        }
+      sum+= exp[j];
+    }
+    sum+= exp[n - 1];
+  }
+}
+
+poly vandermonde::numvec2poly( const number * q )
+{
+  int j;
+  long i,c,sum;
+  number tmp;
+
+  poly pnew,pit=NULL;
+
+  c=0;
+  sum=0;
+
+  int *exp= (int *) omAlloc( (n+1) * sizeof(int) );
+
+  for ( j= 0; j < n+1; j++ ) exp[j]=0;
+
+  for ( i= 0; i < l; i++ )
+  {
+    if ( (!homog || (sum == maxdeg)) && q[i] && !nIsZero(q[i]) )
+    {
+      pnew= pOne();
+      pSetCoeff(pnew,q[i]);
+      pSetExpV(pnew,exp);
+      if ( pit )
+      {
+        pNext(pnew)= pit;
+        pit= pnew;
+      }
+      else
+      {
+        pit= pnew;
+        pNext(pnew)= NULL;
+      }
+      pSetm(pit);
+    }
+    exp[1]++;
+    sum=0;
+    for ( j= 1; j < n; j++ )
+    {
+      if ( exp[j] > maxdeg )
+      {
+        exp[j]= 0;
+        exp[j + 1]++;
+        }
+      sum+= exp[j];
+    }
+    sum+= exp[n];
+  }
+
+  omFreeSize( (ADDRESS) exp, (n+1) * sizeof(int) );
+
+  pSortAdd(pit);
+  return pit;
+}
+
+number * vandermonde::interpolateDense( const number * q )
+{
+  int i,j,k;
+  number newnum,tmp1;
+  number b,t,xx,s;
+  number *c;
+  number *w;
+
+  b=t=xx=s=tmp1=NULL;
+
+  w= (number *)omAlloc( cn * sizeof(number) );
+  c= (number *)omAlloc( cn * sizeof(number) );
+  for ( j= 0; j < cn; j++ )
+  {
+    w[j]= nInit(0);
+    c[j]= nInit(0);
+  }
+
+  if ( cn == 1 )
+  {
+    nDelete( &w[0] );
+    w[0]= nCopy(q[0]);
+  }
+  else
+  {
+    nDelete( &c[cn-1] );
+    c[cn-1]= nCopy(x[0]);
+    c[cn-1]= nNeg(c[cn-1]);              // c[cn]= -x[1]
+
+    for ( i= 1; i < cn; i++ ) {              // i=2; i <= cn
+      nDelete( &xx );
+      xx= nCopy(x[i]);
+      xx= nNeg(xx);               // xx= -x[i]
+
+      for ( j= (cn-i-1); j <= (cn-2); j++) { // j=(cn+1-i); j <= (cn-1)
+        nDelete( &tmp1 );
+        tmp1= nMult( xx, c[j+1] );           // c[j]= c[j] + (xx * c[j+1])
+        newnum= nAdd( c[j], tmp1 );
+        nDelete( &c[j] );
+        c[j]= newnum;
+      }
+
+      newnum= nAdd( xx, c[cn-1] );           // c[cn-1]= c[cn-1] + xx
+      nDelete( &c[cn-1] );
+      c[cn-1]= newnum;
+    }
+
+    for ( i= 0; i < cn; i++ ) {              // i=1; i <= cn
+      nDelete( &xx );
+      xx= nCopy(x[i]);                     // xx= x[i]
+
+      nDelete( &t );
+      t= nInit( 1 );                         // t= b= 1
+      nDelete( &b );
+      b= nInit( 1 );
+      nDelete( &s );                         // s= q[cn-1]
+      s= nCopy( q[cn-1] );
+
+      for ( k= cn-1; k >= 1; k-- ) {         // k=cn; k >= 2
+        nDelete( &tmp1 );
+        tmp1= nMult( xx, b );                // b= c[k] + (xx * b)
+        nDelete( &b );
+        b= nAdd( c[k], tmp1 );
+
+        nDelete( &tmp1 );
+        tmp1= nMult( q[k-1], b );            // s= s + (q[k-1] * b)
+        newnum= nAdd( s, tmp1 );
+        nDelete( &s );
+        s= newnum;
+
+        nDelete( &tmp1 );
+        tmp1= nMult( xx, t );                // t= (t * xx) + b
+        newnum= nAdd( tmp1, b );
+        nDelete( &t );
+        t= newnum;
+      }
+
+      if (!nIsZero(t))
+      {
+        nDelete( &w[i] );                      // w[i]= s/t
+        w[i]= nDiv( s, t );
+        nNormalize( w[i] );
+      }
+
+      mprSTICKYPROT(ST_VANDER_STEP);
+    }
+  }
+  mprSTICKYPROT("\n");
+
+  // free mem
+  for ( j= 0; j < cn; j++ ) nDelete( c+j );
+  omFreeSize( (ADDRESS)c, cn * sizeof( number ) );
+
+  nDelete( &tmp1 );
+  nDelete( &s );
+  nDelete( &t );
+  nDelete( &b );
+  nDelete( &xx );
+
+  // makes quotiens smaller
+  for ( j= 0; j < cn; j++ ) nNormalize( w[j] );
+
+  return w;
+}
+//<-
+
+//-----------------------------------------------------------------------------
+//-------------- rootContainer ------------------------------------------------
+//-----------------------------------------------------------------------------
+
+//-> definitions
+#define MR       8        // never change this value
+#define MT      5
+#define MMOD    (MT*MR)
+#define MAXIT   (5*MMOD)   // max number of iterations in laguer root finder
+
+
+//-> rootContainer::rootContainer()
+rootContainer::rootContainer()
+{
+  rt=none;
+
+  coeffs= NULL;
+  ievpoint= NULL;
+  theroots= NULL;
+
+  found_roots= false;
+}
+//<-
+
+//-> rootContainer::~rootContainer()
+rootContainer::~rootContainer()
+{
+  int i;
+  int n= pVariables;
+
+  // free coeffs, ievpoint
+  if ( ievpoint != NULL )
+  {
+    for ( i=0; i < anz+2; i++ ) nDelete( ievpoint + i );
+    omFreeSize( (ADDRESS)ievpoint, (anz+2) * sizeof( number ) );
+  }
+
+  for ( i=0; i <= tdg; i++ ) nDelete( coeffs + i );
+  omFreeSize( (ADDRESS)coeffs, (tdg+1) * sizeof( number ) );
+
+  // theroots löschen
+  for ( i=0; i < tdg; i++ ) delete theroots[i];
+  omFreeSize( (ADDRESS) theroots, (tdg)*sizeof(gmp_complex*) );
+
+  mprPROTnl("~rootContainer()");
+}
+//<-
+
+//-> void rootContainer::fillContainer( ... )
+void rootContainer::fillContainer( number *_coeffs, number *_ievpoint,
+                                   const int _var, const int _tdg,
+                                   const rootType  _rt, const int _anz )
+{
+  int i;
+  number nn= nInit(0);
+  var=_var;
+  tdg=_tdg;
+  coeffs=_coeffs;
+  rt=_rt;
+  anz=_anz;
+
+  for ( i=0; i <= tdg; i++ )
+  {
+    if ( nEqual(coeffs[i],nn) )
+    {
+      nDelete( &coeffs[i] );
+      coeffs[i]=NULL;
+    }
+  }
+  nDelete( &nn );
+
+  if ( rt == cspecialmu && _ievpoint ) { // copy ievpoint
+    ievpoint= (number *)omAlloc( (anz+2) * sizeof( number ) );
+    for (i=0; i < anz+2; i++) ievpoint[i]= nCopy( _ievpoint[i] );
+  }
+
+  theroots= NULL;
+  found_roots= false;
+}
+//<-
+
+//-> poly rootContainer::getPoly()
+poly rootContainer::getPoly()
+{
+  int i;
+
+  poly result= NULL;
+  poly ppos;
+
+  if ( (rt == cspecial) || ( rt == cspecialmu ) )
+  {
+    for ( i= tdg; i >= 0; i-- )
+    {
+      if ( coeffs[i] )
+      {
+        poly p= pOne();
+        //pSetExp( p, var+1, i);
+        pSetExp( p, 1, i);
+        pSetCoeff( p, nCopy( coeffs[i] ) );
+        pSetm( p );
+        if (result)
+        {
+          ppos->next=p;
+          ppos=ppos->next;
+        }
+        else
+        {
+          result=p;
+          ppos=p;
+        }
+
+      }
+    }
+    pSetm( result );
+  }
+
+  return result;
+}
+//<-
+
+//-> const gmp_complex & rootContainer::opterator[] ( const int i )
+// this is now inline!
+//  gmp_complex & rootContainer::operator[] ( const int i )
+//  {
+//    if ( found_roots && ( i >= 0) && ( i < tdg ) )
+//    {
+//      return *theroots[i];
+//    }
+//    // warning
+//    Warn("rootContainer::getRoot: Wrong index %d, found_roots %s",i,found_roots?"true":"false");
+//    gmp_complex *tmp= new gmp_complex();
+//    return *tmp;
+//  }
+//<-
+
+//-> gmp_complex & rootContainer::evPointCoord( int i )
+gmp_complex & rootContainer::evPointCoord( const int i )
+{
+  if (! ((i >= 0) && (i < anz+2) ) )
+    WarnS("rootContainer::evPointCoord: index out of range");
+  if (ievpoint == NULL)
+    WarnS("rootContainer::evPointCoord: ievpoint == NULL");
+
+  if ( (rt == cspecialmu) && found_roots ) {  // FIX ME
+    if ( ievpoint[i] != NULL )
+    {
+      gmp_complex *tmp= new gmp_complex();
+      *tmp= numberToComplex(ievpoint[i]);
+      return *tmp;
+    }
+    else
+    {
+      Warn("rootContainer::evPointCoord: NULL index %d",i);
+    }
+  }
+
+  // warning
+  Warn("rootContainer::evPointCoord: Wrong index %d, found_roots %s",i,found_roots?"true":"false");
+  gmp_complex *tmp= new gmp_complex();
+  return *tmp;
+}
+//<-
+
+//-> bool rootContainer::changeRoots( int from, int to )
+bool rootContainer::swapRoots( const int from, const int to )
+{
+  if ( found_roots && ( from >= 0) && ( from < tdg ) && ( to >= 0) && ( to < tdg ) )
+  {
+    if ( to != from )
+    {
+      gmp_complex tmp( *theroots[from] );
+      *theroots[from]= *theroots[to];
+      *theroots[to]= tmp;
+    }
+    return true;
+  }
+
+  // warning
+  Warn(" rootContainer::changeRoots: Wrong index %d, %d",from,to);
+  return false;
+}
+//<-
+
+//-> void rootContainer::solver()
+bool rootContainer::solver( const int polishmode )
+{
+  int i;
+
+  // there are maximal tdg roots, so *roots ranges form 0 to tdg-1.
+  theroots= (gmp_complex**)omAlloc( tdg*sizeof(gmp_complex*) );
+  for ( i=0; i < tdg; i++ ) theroots[i]= new gmp_complex();
+
+  // copy the coefficients of type number to type gmp_complex
+  gmp_complex **ad= (gmp_complex**)omAlloc( (tdg+1)*sizeof(gmp_complex*) );
+  for ( i=0; i <= tdg; i++ )
+  {
+    ad[i]= new gmp_complex();
+    if ( coeffs[i] ) *ad[i] = numberToComplex( coeffs[i] );
+  }
+
+  // now solve
+  found_roots= laguer_driver( ad, theroots, polishmode != 0 );
+  if (!found_roots)
+    WarnS("rootContainer::solver: No roots found!");
+ 
+  // free memory
+  for ( i=0; i <= tdg; i++ ) delete ad[i];
+  omFreeSize( (ADDRESS) ad, (tdg+1)*sizeof(gmp_complex*) );
+
+  return found_roots;
+}
+//<-
+
+//-> gmp_complex* rootContainer::laguer_driver( bool polish )
+bool rootContainer::laguer_driver(gmp_complex ** a, gmp_complex ** roots, bool polish )
+{
+  int i,j,k,its;
+  gmp_float zero(0.0);
+  gmp_complex x(0.0),o(1.0);
+  bool ret= true, isf=isfloat(a), type=true;
+
+  gmp_complex ** ad= (gmp_complex**)omAlloc( (tdg+1)*sizeof(gmp_complex*) );
+  for ( i=0; i <= tdg; i++ ) ad[i]= new gmp_complex( *a[i] );
+
+  k = 0;
+  i = tdg;
+  j = i-1;
+  while (i>2)
+  {
+    // run laguer alg
+    x = zero;
+    laguer(ad, i, &x, &its, type);
+    if ( its > MAXIT )
+    {
+      type = !type;
+      x = zero;
+      laguer(ad, i, &x, &its, type);
+    }
+
+    mprSTICKYPROT(ST_ROOTS_LGSTEP);
+    if ( its > MAXIT )
+    {  // error
+      WarnS("rootContainer::laguer_driver: To many iterations!");
+      ret= false;
+      goto theend;
+    }
+    if ( polish )
+    {
+      laguer( a, tdg, &x, &its , type);
+      if ( its > MAXIT )
+      {  // error
+        WarnS("rootContainer::laguer_driver: To many iterations in polish!");
+        ret= false;
+        goto theend;
+      }
+    }
+    if (!type) x = o/x;
+    if (x.imag() == zero)
+    {
+      *roots[k] = x;
+      k++;
+      divlin(ad,x,i);
+      i--;
+    }
+    else
+    {
+      if(isf)
+      {
+        *roots[j] = x;
+        *roots[j-1]= gmp_complex(x.real(),-x.imag());
+        j -= 2;
+        divquad(ad,x,i);
+        i -= 2;
+      }
+      else
+      {
+        *roots[j] = x;
+        j--;
+        divlin(ad,x,i);
+        i--;
+      }
+    }
+    type = !type;
+  }
+  solvequad(ad,roots,k,j);
+  sortroots(roots,k,j,isf);
+
+theend:
+  mprSTICKYPROT("\n");
+  for ( i=0; i <= tdg; i++ ) delete ad[i];
+  omFreeSize( (ADDRESS) ad, (tdg+1)*sizeof( gmp_complex* ));
+
+  return ret;
+}
+//<-
+
+//-> void rootContainer::laguer(...)
+void rootContainer::laguer(gmp_complex ** a, int m, gmp_complex *x, int *its, bool type)
+{
+  int iter,j;
+  gmp_float zero(0.0),one(1.0),deg(m);
+  gmp_float abx_g, err_g, fabs;
+  gmp_complex dx, x1, b, d, f, g, h, sq, gp, gm, g2;
+  gmp_float frac_g[MR+1] = { 0.0, 0.5, 0.25, 0.75, 0.125, 0.375, 0.625, 0.875, 1.0 };
+
+  gmp_float epss(0.1);
+  mpf_pow_ui(*epss._mpfp(),*epss.mpfp(),getGMPFloatDigits());
+
+  for ( iter= 1; iter <= MAXIT; iter++ )
+  {
+    mprSTICKYPROT(ST_ROOTS_LG);
+    *its=iter;
+    if (type)
+      computefx(a,*x,m,b,d,f,abx_g,err_g);
+    else
+      computegx(a,*x,m,b,d,f,abx_g,err_g);
+    err_g *= epss; // EPSS;
+
+    fabs = abs(b);
+    if (fabs <= err_g)
+    {
+      if ((fabs==zero) || (abs(d)==zero)) return;
+      *x -= (b/d); // a last newton-step
+      goto ende;
+    }
+
+    g= d / b;
+    g2 = g * g;
+    h= g2 - (((f+f) / b ));
+    sq= sqrt(( ( h * deg ) - g2 ) * (deg - one));
+    gp= g + sq;
+    gm= g - sq;
+    if (abs(gp)<abs(gm))
+    {
+      dx = deg/gm;
+    }
+    else
+    {
+      if((gp.real()==zero)&&(gp.imag()==zero))
+      {
+        dx.real(cos((mprfloat)iter));
+        dx.imag(sin((mprfloat)iter));
+        dx = dx*(one+abx_g);
+      }
+      else
+      {
+        dx = deg/gp;
+      }
+    }
+    x1= *x - dx;
+
+    if (*x == x1) goto ende;
+
+    j = iter%MMOD;
+    if (j==0) j=MT;
+    if ( j % MT ) *x= x1;
+    else *x -= ( dx * frac_g[ j / MT ] );
+  }
+
+  *its= MAXIT+1;
+ende:
+  checkimag(x,epss);
+}
+
+void rootContainer::checkimag(gmp_complex *x, gmp_float &e)
+{
+  if(abs(x->imag())<abs(x->real())*e)
+  {
+    x->imag(0.0);
+  }
+}
+
+bool rootContainer::isfloat(gmp_complex **a)
+{
+  gmp_float z(0.0);
+  gmp_complex *b;
+  for (int i=tdg; i >= 0; i-- )
+  {
+    b = &(*a[i]);
+    if (!(b->imag()==z))
+      return false;
+  }
+  return true;
+}
+
+void rootContainer::divlin(gmp_complex **a, gmp_complex x, int j)
+{
+  int i;
+  gmp_float o(1.0);
+
+  if (abs(x)<o)
+  {
+    for (i= j-1; i > 0; i-- )
+      *a[i] += (*a[i+1]*x);
+    for (i= 0; i < j; i++ )
+      *a[i] = *a[i+1];
+  }
+  else
+  {
+    gmp_complex y(o/x);
+    for (i= 1; i < j; i++)
+      *a[i] += (*a[i-1]*y);
+  }
+}
+
+void rootContainer::divquad(gmp_complex **a, gmp_complex x, int j)
+{
+  int i;
+  gmp_float o(1.0),p(x.real()+x.real()),
+            q((x.real()*x.real())+(x.imag()*x.imag()));
+
+  if (abs(x)<o)
+  {
+    *a[j-1] += (*a[j]*p);
+    for (i= j-2; i > 1; i-- )
+      *a[i] += ((*a[i+1]*p)-(*a[i+2]*q));
+    for (i= 0; i < j-1; i++ )
+      *a[i] = *a[i+2];
+  }
+  else
+  {
+    p = p/q;
+    q = o/q;
+    *a[1] += (*a[0]*p);
+    for (i= 2; i < j-1; i++)
+      *a[i] += ((*a[i-1]*p)-(*a[i-2]*q));
+  }
+}
+
+void rootContainer::solvequad(gmp_complex **a, gmp_complex **r, int &k, int &j)
+{
+  gmp_float zero(0.0);
+
+  if (j>k)
+  {
+    gmp_complex sq(zero);
+    gmp_complex h1(*a[1]/(*a[2] + *a[2])), h2(*a[0] / *a[2]);
+    gmp_complex disk((h1 * h1) - h2);
+    if (disk.imag()==zero)
+    {
+      if (disk.real()<zero)
+      {
+        sq.real(zero);
+        sq.imag(sqrt(-disk.real()));
+      }
+      else
+        sq = (gmp_complex)sqrt(disk.real());
+    }
+    else
+      sq = sqrt(disk);
+    *r[k+1] = sq - h1;
+    sq += h1;
+    *r[k] = (gmp_complex)0.0-sq;
+    if(sq.imag()==zero)
+    {
+      k = j;
+      j++;
+    }
+    else
+    {
+      j = k;
+      k--;
+    }
+  }
+  else
+  {
+    *r[k]= (gmp_complex)0.0-(*a[0] / *a[1]);
+    if(r[k]->imag()==zero)
+      j++;
+    else
+      k--;
+  }
+}
+
+void rootContainer::sortroots(gmp_complex **ro, int r, int c, bool isf)
+{
+  int j;
+
+  for (j=0; j<r; j++) // the real roots
+    sortre(ro, j, r, 1);
+  if (c>=tdg) return;
+  if (isf)
+  {
+    for (j=c; j+2<tdg; j+=2) // the complex roots for a real poly
+      sortre(ro, j, tdg-1, 2);
+  }
+  else
+  {
+    for (j=c; j+1<tdg; j++) // the complex roots for a general poly
+      sortre(ro, j, tdg-1, 1);
+  }
+}
+
+void rootContainer::sortre(gmp_complex **r, int l, int u, int inc)
+{
+  int pos,i;
+  gmp_complex *x,*y;
+
+  pos = l;
+  x = r[pos];
+  for (i=l+inc; i<=u; i+=inc)
+  {
+    if (r[i]->real()<x->real())
+    {
+      pos = i;
+      x = r[pos];
+    }
+  }
+  if (pos>l)
+  {
+    if (inc==1)
+    {
+      for (i=pos; i>l; i--)
+        r[i] = r[i-1];
+      r[l] = x;
+    }
+    else
+    {
+      y = r[pos+1];
+      for (i=pos+1; i+1>l; i--)
+        r[i] = r[i-2];
+      if (x->imag()>y->imag())
+      {
+        r[l] = x;
+        r[l+1] = y;
+      }
+      else
+      {
+        r[l] = y;
+        r[l+1] = x;
+      }
+    }
+  }
+  else if ((inc==2)&&(x->imag()<r[l+1]->imag()))
+  {
+    r[l] = r[l+1];
+    r[l+1] = x;
+  }
+}
+
+void rootContainer::computefx(gmp_complex **a, gmp_complex x, int m,
+                  gmp_complex &f0, gmp_complex &f1, gmp_complex &f2,
+                  gmp_float &ex, gmp_float &ef)
+{
+  int k;
+
+  f0= *a[m];
+  ef= abs(f0);
+  f1= gmp_complex(0.0);
+  f2= f1;
+  ex= abs(x);
+
+  for ( k= m-1; k >= 0; k-- )
+  {
+    f2 = ( x * f2 ) + f1;
+    f1 = ( x * f1 ) + f0;
+    f0 = ( x * f0 ) + *a[k];
+    ef = abs( f0 ) + ( ex * ef );
+  }
+}
+
+void rootContainer::computegx(gmp_complex **a, gmp_complex x, int m,
+                  gmp_complex &f0, gmp_complex &f1, gmp_complex &f2,
+                  gmp_float &ex, gmp_float &ef)
+{
+  int k;
+
+  f0= *a[0];
+  ef= abs(f0);
+  f1= gmp_complex(0.0);
+  f2= f1;
+  ex= abs(x);
+
+  for ( k= 1; k <= m; k++ )
+  {
+    f2 = ( x * f2 ) + f1;
+    f1 = ( x * f1 ) + f0;
+    f0 = ( x * f0 ) + *a[k];
+    ef = abs( f0 ) + ( ex * ef );
+  }
+}
+
+//-----------------------------------------------------------------------------
+//-------------- rootArranger -------------------------------------------------
+//-----------------------------------------------------------------------------
+
+//-> rootArranger::rootArranger(...)
+rootArranger::rootArranger( rootContainer ** _roots,
+                            rootContainer ** _mu,
+                            const int _howclean )
+  : roots(_roots), mu(_mu), howclean(_howclean)
+{
+  found_roots=false;
+}
+//<-
+
+//-> void rootArranger::solve_all()
+void rootArranger::solve_all()
+{
+  int i;
+  found_roots= true;
+
+  // find roots of polys given by coeffs in roots
+  rc= roots[0]->getAnzElems();
+  for ( i= 0; i < rc; i++ )
+    if ( !roots[i]->solver( howclean ) )
+    {
+      found_roots= false;
+      return;
+    }
+  // find roots of polys given by coeffs in mu
+  mc= mu[0]->getAnzElems();
+  for ( i= 0; i < mc; i++ )
+    if ( ! mu[i]->solver( howclean ) )
+    {
+      found_roots= false;
+      return;
+    }
+}
+//<-
+
+//-> void rootArranger::arrange()
+void rootArranger::arrange()
+{
+  gmp_complex tmp,zwerg;
+  int anzm= mu[0]->getAnzElems();
+  int anzr= roots[0]->getAnzRoots();
+  int xkoord, r, rtest, xk, mtest;
+  bool found;
+  //gmp_complex mprec(1.0/pow(10,gmp_output_digits-5),1.0/pow(10,gmp_output_digits-5));
+  gmp_float mprec(1.0/pow(10.0,(int)(gmp_output_digits/3)));
+
+  for ( xkoord= 0; xkoord < anzm; xkoord++ ) {    // für x1,x2, x1,x2,x3, x1,x2,...,xn
+    for ( r= 0; r < anzr; r++ ) {                 // für jede Nullstelle
+      // (x1-koordinate) * evp[1] + (x2-koordinate) * evp[2] +
+      //                                  ... + (xkoord-koordinate) * evp[xkoord]
+      tmp= gmp_complex();
+      for ( xk =0; xk <= xkoord; xk++ )
+      {
+        tmp -= (*roots[xk])[r] * mu[xkoord]->evPointCoord(xk+1); //xk+1
+      }
+      found= false;
+      for ( rtest= r; rtest < anzr; rtest++ ) {   // für jede Nullstelle
+        zwerg = tmp - (*roots[xk])[rtest] * mu[xkoord]->evPointCoord(xk+1); // xk+1, xkoord+2
+        for ( mtest= 0; mtest < anzr; mtest++ )
+        {
+          //          if ( tmp == (*mu[xkoord])[mtest] )
+          //          {
+          if ( ((zwerg.real() <= (*mu[xkoord])[mtest].real() + mprec) &&
+                (zwerg.real() >= (*mu[xkoord])[mtest].real() - mprec)) &&
+               ((zwerg.imag() <= (*mu[xkoord])[mtest].imag() + mprec) &&
+                (zwerg.imag() >= (*mu[xkoord])[mtest].imag() - mprec)) )
+           {
+             roots[xk]->swapRoots( r, rtest );
+             found= true;
+             break;
+           }
+        }
+      } // rtest
+      if ( !found )
+      {
+        Warn("rootArranger::arrange: No match? coord %d, root %d.",xkoord,r);
+#ifdef mprDEBUG_PROT
+        WarnS("One of these ...");
+        for ( rtest= r; rtest < anzr; rtest++ )
+        {
+          tmp= gmp_complex();
+          for ( xk =0; xk <= xkoord; xk++ )
+          {
+            tmp-= (*roots[xk])[r] * mu[xkoord]->evPointCoord(xk+1);
+          }
+          tmp-= (*roots[xk])[rtest] * mu[xkoord]->evPointCoord(xk+1); // xkoord+2
+          Warn("  %s",complexToStr(tmp,gmp_output_digits+1),rtest);
+        }
+        WarnS(" ... must match to one of these:");
+        for ( mtest= 0; mtest < anzr; mtest++ )
+        {
+          Warn("                  %s",complexToStr((*mu[xkoord])[mtest],gmp_output_digits+1));
+        }
+#endif
+      }
+    } // r
+  } // xkoord
+}
+//<-
+
+//-----------------------------------------------------------------------------
+//-------------- simplex ----- ------------------------------------------------
+//-----------------------------------------------------------------------------
+
+//  #ifdef mprDEBUG_PROT
+//  #define error(a) a
+//  #else
+//  #define error(a)
+//  #endif
+
+#define error(a) a
+
+#define MAXPOINTS      1000
+
+//-> simplex::*
+//
+simplex::simplex( int rows, int cols )
+   : LiPM_cols(cols), LiPM_rows(rows)
+{
+  int i;
+
+  LiPM_rows=LiPM_rows+3;
+  LiPM_cols=LiPM_cols+2;
+
+  LiPM = (mprfloat **)omAlloc( LiPM_rows * sizeof(mprfloat *) );  // LP matrix
+  for( i= 0; i < LiPM_rows; i++ )
+  {
+    // Mem must be allocated aligned, also for type double!
+    LiPM[i] = (mprfloat *)omAlloc0Aligned( LiPM_cols * sizeof(mprfloat) );
+  }
+
+  iposv = (int *)omAlloc0( 2*LiPM_rows*sizeof(int) );
+  izrov = (int *)omAlloc0( 2*LiPM_rows*sizeof(int) );
+
+  m=n=m1=m2=m3=icase=0;
+
+#ifdef mprDEBUG_ALL
+  Print("LiPM size: %d, %d\n",LiPM_rows,LiPM_cols);
+#endif
+}
+
+simplex::~simplex()
+{
+  // clean up
+  int i;
+  for( i= 0; i < LiPM_rows; i++ )
+  {
+    omFreeSize( (ADDRESS) LiPM[i], LiPM_cols * sizeof(mprfloat) );
+  }
+  omFreeSize( (ADDRESS) LiPM, LiPM_rows * sizeof(mprfloat *) );
+
+  omFreeSize( (ADDRESS) iposv, 2*LiPM_rows*sizeof(int) );
+  omFreeSize( (ADDRESS) izrov, 2*LiPM_rows*sizeof(int) );
+}
+
+BOOLEAN simplex::mapFromMatrix( matrix m )
+{
+  int i,j;
+//    if ( MATROWS( m ) > LiPM_rows ||  MATCOLS( m ) > LiPM_cols ) {
+//      WarnS("");
+//      return FALSE;
+//    }
+
+  number coef;
+  for ( i= 1; i <= MATROWS( m ); i++ )
+  {
+     for ( j= 1; j <= MATCOLS( m ); j++ )
+     {
+        if ( MATELEM(m,i,j) != NULL )
+        {
+           coef= pGetCoeff( MATELEM(m,i,j) );
+           if ( coef != NULL && !nIsZero(coef) )
+              LiPM[i][j]= (double)(*(gmp_float*)coef);
+           //#ifdef mpr_DEBUG_PROT
+           //Print("%f ",LiPM[i][j]);
+           //#endif
+        }
+     }
+     //     PrintLn();
+  }
+
+  return TRUE;
+}
+
+matrix simplex::mapToMatrix( matrix m )
+{
+  int i,j;
+//    if ( MATROWS( m ) < LiPM_rows-3 ||  MATCOLS( m ) < LiPM_cols-2 ) {
+//      WarnS("");
+//      return NULL;
+//    }
+
+//Print(" %d x %d\n",MATROWS( m ),MATCOLS( m ));
+
+  number coef;
+  gmp_float * bla;
+  for ( i= 1; i <= MATROWS( m ); i++ )
+  {
+    for ( j= 1; j <= MATCOLS( m ); j++ )
+    {
+       pDelete( &(MATELEM(m,i,j)) );
+       MATELEM(m,i,j)= NULL;
+//Print(" %3.0f ",LiPM[i][j]);
+       if ( LiPM[i][j] != 0.0 )
+       {
+          bla= new gmp_float(LiPM[i][j]);
+          coef= (number)bla;
+          MATELEM(m,i,j)= pOne();
+          pSetCoeff( MATELEM(m,i,j), coef );
+       }
+    }
+//PrintLn();
+  }
+
+  return m;
+}
+
+intvec * simplex::posvToIV()
+{
+   int i;
+   intvec * iv = new intvec( m );
+   for ( i= 1; i <= m; i++ )
+   {
+      IMATELEM(*iv,i,1)= iposv[i];
+   }
+   return iv;
+}
+
+intvec * simplex::zrovToIV()
+{
+   int i;
+   intvec * iv = new intvec( n );
+   for ( i= 1; i <= n; i++ )
+   {
+      IMATELEM(*iv,i,1)= izrov[i];
+   }
+   return iv;
+}
+
+void simplex::compute()
+{
+  int i,ip,ir,is,k,kh,kp,m12,nl1,nl2;
+  int *l1,*l2,*l3;
+  mprfloat q1, bmax;
+
+  if ( m != (m1+m2+m3) )
+  {
+    // error: bad input
+    error(WarnS("simplex::compute: Bad input constraint counts!");)
+    icase=-2;
+    return;
+  }
+
+  l1= (int *) omAlloc0( (n+1) * sizeof(int) );
+  l2= (int *) omAlloc0( (m+1) * sizeof(int) );
+  l3= (int *) omAlloc0( (m+1) * sizeof(int) );
+
+  nl1= n;
+  for ( k=1; k<=n; k++ ) l1[k]=izrov[k]=k;
+  nl2=m;
+  for ( i=1; i<=m; i++ )
+  {
+    if ( LiPM[i+1][1] < 0.0 )
+    {
+      // error: bad input
+      error(WarnS("simplex::compute: Bad input tableau!");)
+      error(Warn("simplex::compute: in input Matrix row %d, column 1, value %f",i+1,LiPM[i+1][1]);)
+      icase=-2;
+      // free mem l1,l2,l3;
+      omFreeSize( (ADDRESS) l3, (m+1) * sizeof(int) );
+      omFreeSize( (ADDRESS) l2, (m+1) * sizeof(int) );
+      omFreeSize( (ADDRESS) l1, (n+1) * sizeof(int) );
+      return;
+    }
+    l2[i]= i;
+    iposv[i]= n+i;
+  }
+  for ( i=1; i<=m2; i++) l3[i]= 1;
+  ir= 0;
+  if (m2+m3)
+  {
+    ir=1;
+    for ( k=1; k <= (n+1); k++ )
+    {
+      q1=0.0;
+      for ( i=m1+1; i <= m; i++ ) q1+= LiPM[i+1][k];
+      LiPM[m+2][k]= -q1;
+    }
+
+    do
+    {
+      simp1(LiPM,m+1,l1,nl1,0,&kp,&bmax);
+      if ( bmax <= SIMPLEX_EPS && LiPM[m+2][1] < -SIMPLEX_EPS )
+      {
+        icase= -1; // no solution found
+        // free mem l1,l2,l3;
+        omFreeSize( (ADDRESS) l3, (m+1) * sizeof(int) );
+        omFreeSize( (ADDRESS) l2, (m+1) * sizeof(int) );
+        omFreeSize( (ADDRESS) l1, (n+1) * sizeof(int) );
+        return;
+      }
+      else if ( bmax <= SIMPLEX_EPS && LiPM[m+2][1] <= SIMPLEX_EPS )
+      {
+        m12= m1+m2+1;
+        if ( m12 <= m )
+        {
+          for ( ip= m12; ip <= m; ip++ )
+          {
+            if ( iposv[ip] == (ip+n) )
+            {
+              simp1(LiPM,ip,l1,nl1,1,&kp,&bmax);
+              if ( fabs(bmax) >= SIMPLEX_EPS)
+                goto one;
+            }
+          }
+        }
+        ir= 0;
+        --m12;
+        if ( m1+1 <= m12 )
+          for ( i=m1+1; i <= m12; i++ )
+            if ( l3[i-m1] == 1 )
+              for ( k=1; k <= n+1; k++ )
+                LiPM[i+1][k] = -(LiPM[i+1][k]);
+        break;
+      }
+      //#if DEBUG
+      //print_bmat( a, m+2, n+3);
+      //#endif
+      simp2(LiPM,n,l2,nl2,&ip,kp,&q1);
+      if ( ip == 0 )
+      {
+        icase = -1; // no solution found
+        // free mem l1,l2,l3;
+        omFreeSize( (ADDRESS) l3, (m+1) * sizeof(int) );
+        omFreeSize( (ADDRESS) l2, (m+1) * sizeof(int) );
+        omFreeSize( (ADDRESS) l1, (n+1) * sizeof(int) );
+        return;
+      }
+    one: simp3(LiPM,m+1,n,ip,kp);
+      // #if DEBUG
+      // print_bmat(a,m+2,n+3);
+      // #endif
+      if ( iposv[ip] >= (n+m1+m2+1))
+      {
+        for ( k= 1; k <= nl1; k++ )
+          if ( l1[k] == kp ) break;
+        --nl1;
+        for ( is=k; is <= nl1; is++ ) l1[is]= l1[is+1];
+        ++(LiPM[m+2][kp+1]);
+        for ( i= 1; i <= m+2; i++ ) LiPM[i][kp+1] = -(LiPM[i][kp+1]);
+      }
+      else
+      {
+        if ( iposv[ip] >= (n+m1+1) )
+        {
+          kh= iposv[ip]-m1-n;
+          if ( l3[kh] )
+          {
+            l3[kh]= 0;
+            ++(LiPM[m+2][kp+1]);
+            for ( i=1; i<= m+2; i++ )
+              LiPM[i][kp+1] = -(LiPM[i][kp+1]);
+          }
+        }
+      }
+      is= izrov[kp];
+      izrov[kp]= iposv[ip];
+      iposv[ip]= is;
+    } while (ir);
+  }
+  /* end of phase 1, have feasible sol, now optimize it */
+  loop
+  {
+    // #if DEBUG
+    // print_bmat( a, m+1, n+5);
+    // #endif
+    simp1(LiPM,0,l1,nl1,0,&kp,&bmax);
+    if (bmax <= /*SIMPLEX_EPS*/0.0)
+    {
+      icase=0; // finite solution found
+      // free mem l1,l2,l3
+      omFreeSize( (ADDRESS) l3, (m+1) * sizeof(int) );
+      omFreeSize( (ADDRESS) l2, (m+1) * sizeof(int) );
+      omFreeSize( (ADDRESS) l1, (n+1) * sizeof(int) );
+      return;
+    }
+    simp2(LiPM,n,l2,nl2,&ip,kp,&q1);
+    if (ip == 0)
+    {
+      //printf("Unbounded:");
+      // #if DEBUG
+      //       print_bmat( a, m+1, n+1);
+      // #endif
+      icase=1;                /* unbounded */
+      // free mem
+      omFreeSize( (ADDRESS) l3, (m+1) * sizeof(int) );
+      omFreeSize( (ADDRESS) l2, (m+1) * sizeof(int) );
+      omFreeSize( (ADDRESS) l1, (n+1) * sizeof(int) );
+      return;
+    }
+    simp3(LiPM,m,n,ip,kp);
+    is= izrov[kp];
+    izrov[kp]= iposv[ip];
+    iposv[ip]= is;
+  }/*for ;;*/
+}
+
+void simplex::simp1( mprfloat **a, int mm, int ll[], int nll, int iabf, int *kp, mprfloat *bmax )
+{
+  int k;
+  mprfloat test;
+
+  if( nll <= 0)
+  {                        /* init'tion: fixed */
+    *bmax = 0.0;
+    return;
+  }
+  *kp=ll[1];
+  *bmax=a[mm+1][*kp+1];
+  for (k=2;k<=nll;k++)
+  {
+    if (iabf == 0)
+    {
+      test=a[mm+1][ll[k]+1]-(*bmax);
+      if (test > 0.0)
+      {
+        *bmax=a[mm+1][ll[k]+1];
+        *kp=ll[k];
+      }
+    }
+    else
+    {                        /* abs values: have fixed it */
+      test=fabs(a[mm+1][ll[k]+1])-fabs(*bmax);
+      if (test > 0.0)
+      {
+        *bmax=a[mm+1][ll[k]+1];
+        *kp=ll[k];
+      }
+    }
+  }
+}
+
+void simplex::simp2( mprfloat **a, int n, int l2[], int nl2, int *ip, int kp, mprfloat *q1 )
+{
+  int k,ii,i;
+  mprfloat qp,q0,q;
+
+  *ip= 0;
+  for ( i=1; i <= nl2; i++ )
+  {
+    if ( a[l2[i]+1][kp+1] < -SIMPLEX_EPS )
+    {
+      *q1= -a[l2[i]+1][1] / a[l2[i]+1][kp+1];
+      *ip= l2[i];
+      for ( i= i+1; i <= nl2; i++ )
+      {
+        ii= l2[i];
+        if (a[ii+1][kp+1] < -SIMPLEX_EPS)
+        {
+          q= -a[ii+1][1] / a[ii+1][kp+1];
+          if (q - *q1 < -SIMPLEX_EPS)
+          {
+            *ip=ii;
+            *q1=q;
+          }
+          else if (q - *q1 < SIMPLEX_EPS)
+          {
+            for ( k=1; k<= n; k++ )
+            {
+              qp= -a[*ip+1][k+1]/a[*ip+1][kp+1];
+              q0= -a[ii+1][k+1]/a[ii+1][kp+1];
+              if ( q0 != qp ) break;
+            }
+            if ( q0 < qp ) *ip= ii;
+          }
+        }
+      }
+    }
+  }
+}
+
+void simplex::simp3( mprfloat **a, int i1, int k1, int ip, int kp )
+{
+  int kk,ii;
+  mprfloat piv;
+
+  piv= 1.0 / a[ip+1][kp+1];
+  for ( ii=1; ii <= i1+1; ii++ )
+  {
+    if ( ii -1 != ip )
+    {
+      a[ii][kp+1] *= piv;
+      for ( kk=1; kk <= k1+1; kk++ )
+        if ( kk-1 != kp )
+          a[ii][kk] -= a[ip+1][kk] * a[ii][kp+1];
+    }
+  }
+  for ( kk=1; kk<= k1+1; kk++ )
+    if ( kk-1 != kp ) a[ip+1][kk] *= -piv;
+  a[ip+1][kp+1]= piv;
+}
+//<-
+
+//-----------------------------------------------------------------------------
+
+//#endif // HAVE_MPR
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-1: "make installg" ***
+// compile-command-2: "make install" ***
+// End: ***
Index: kernel/mpr_numeric.h
===================================================================
--- kernel/mpr_numeric.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/mpr_numeric.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,230 @@
+#ifndef MPR_NUMERIC_H
+#define MPR_NUMERIC_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/* $Id: mpr_numeric.h,v 1.1.1.1 2003-10-06 12:15:58 Singular Exp $ */
+
+/*
+* ABSTRACT - multipolynomial resultants - numeric stuff
+*            ( root finder, vandermonde system solver, simplex )
+*/
+
+//-> include & define stuff
+#include "numbers.h"
+#include "mpr_global.h"
+#include "mpr_complex.h"
+
+// define polish mode when finding roots
+#define PM_NONE    0
+#define PM_POLISH  1
+#define PM_CORRUPT 2
+//<-
+
+//-> vandermonde system solver
+/**
+ * vandermonde system solver for interpolating polynomials from their values
+ */
+class vandermonde
+{
+public:
+  vandermonde( const long _cn, const long _n,
+	       const long _maxdeg, number *_p, const bool _homog = true );
+  ~vandermonde();
+
+  /** Solves the Vandermode linear system
+   *    \sum_{i=1}^{n} x_i^k-1 w_i = q_k, k=1,..,n.
+     * Any computations are done using type number to get high pecision results.
+   * @param  q n-tuple of results (right hand of equations)
+   * @return w n-tuple of coefficients of resulting polynomial, lowest deg first
+   */
+  number * interpolateDense( const number * q );
+
+  poly numvec2poly(const number * q );
+
+private:
+  void init();
+
+private:
+  long n;       // number of variables
+  long cn;      // real number of coefficients of poly to interpolate
+  long maxdeg;  // degree of the polynomial to interpolate
+  long l;       // max number of coefficients in poly of deg maxdeg = (maxdeg+1)^n
+
+  number *p;    // evaluation point
+  number *x;    // coefficients, determinend by init() from *p
+
+  bool homog;
+};
+//<-
+
+//-> rootContainer
+/**
+ * complex root finder for univariate polynomials based on laguers algorithm
+ */
+class rootContainer
+{
+public:
+  enum rootType { none, cspecial, cspecialmu, det, onepoly };
+
+  rootContainer();
+  ~rootContainer();
+
+  void fillContainer( number *_coeffs, number *_ievpoint,
+		      const int _var, const int _tdg,
+		      const rootType _rt, const int _anz );
+
+  bool solver( const int polishmode= PM_NONE );
+
+  poly getPoly();
+
+  //gmp_complex & operator[] ( const int i );
+  inline gmp_complex & operator[] ( const int i ) {
+    return *theroots[i];
+  }
+  gmp_complex & evPointCoord( const int i );
+
+  inline gmp_complex * getRoot( const int i ) {
+    return theroots[i];
+  }
+
+  bool swapRoots( const int from, const int to );
+
+  int getAnzElems() { return anz; }
+  int getLDim() { return anz; }
+  int getAnzRoots() { return tdg; }
+
+private:
+  rootContainer( const rootContainer & v );
+
+  /** Given the degree tdg and the tdg+1 complex coefficients ad[0..tdg]
+   * (generated from the number coefficients coeffs[0..tdg]) of the polynomial
+   * this routine successively calls "laguer" and finds all m complex roots in
+   * roots[0..tdg]. The bool var "polish" should be input as "true" if polishing
+   * (also by "laguer") is desired, "false" if the roots will be subsequently
+   * polished by other means.
+   */
+  bool laguer_driver( gmp_complex ** a, gmp_complex ** roots, bool polish = true );
+  bool isfloat(gmp_complex **a);
+  void divlin(gmp_complex **a, gmp_complex x, int j);
+  void divquad(gmp_complex **a, gmp_complex x, int j);
+  void solvequad(gmp_complex **a, gmp_complex **r, int &k, int &j);
+  void sortroots(gmp_complex **roots, int r, int c, bool isf);
+  void sortre(gmp_complex **r, int l, int u, int inc);
+
+  /** Given the degree m and the m+1 complex coefficients a[0..m] of the
+   * polynomial, and given the complex value x, this routine improves x by
+   * Laguerre's method until it converges, within the achievable roundoff limit,
+   * to a root of the given polynomial. The number of iterations taken is
+   * returned at its.
+   */
+  void laguer(gmp_complex ** a, int m, gmp_complex * x, int * its, bool type);
+  void computefx(gmp_complex **a, gmp_complex x, int m,
+                gmp_complex &f0, gmp_complex &f1, gmp_complex &f2,
+                gmp_float &ex, gmp_float &ef);
+  void computegx(gmp_complex **a, gmp_complex x, int m,
+                gmp_complex &f0, gmp_complex &f1, gmp_complex &f2,
+                gmp_float &ex, gmp_float &ef);
+  void checkimag(gmp_complex *x, gmp_float &e);
+
+  int var;
+  int tdg;
+
+  number * coeffs;
+  number * ievpoint;
+  rootType rt;
+
+  gmp_complex ** theroots;
+
+  int anz;
+  bool found_roots;
+};
+//<-
+
+//-> class rootArranger
+class rootArranger
+{
+public:
+  rootArranger( rootContainer ** _roots,
+		rootContainer ** _mu,
+		const int _howclean = PM_CORRUPT );
+  ~rootArranger() {}
+
+  void solve_all();
+  void arrange();
+
+  lists listOfRoots( const unsigned int oprec );
+
+  const bool success() { return found_roots; }
+
+private:
+  rootArranger( const rootArranger & );
+
+  rootContainer ** roots;
+  rootContainer ** mu;
+
+  int howclean;
+  int rc,mc;
+  bool found_roots;
+};
+//<-
+
+//-> simplex computation
+//   (used by sparse matrix construction)
+#define SIMPLEX_EPS 1.0e-12
+
+/** Linear Programming / Linear Optimization using Simplex - Algorithm
+ *
+ * On output, the tableau LiPM is indexed by two arrays of integers.
+ * ipsov[j] contains, for j=1..m, the number i whose original variable
+ * is now represented by row j+1 of LiPM. (left-handed vars in solution)
+ * (first row is the one with the objective function)
+ * izrov[j] contains, for j=1..n, the number i whose original variable
+ * x_i is now a right-handed variable, rep. by column j+1 of LiPM.
+ * These vars are all zero in the solution. The meaning of n<i<n+m1+m2
+ * is the same as above.
+ */
+class simplex
+{
+public:
+
+  int m;         // number of constraints, make sure m == m1 + m2 + m3 !!
+  int n;         // # of independent variables
+  int m1,m2,m3;  // constraints <=, >= and ==
+  int icase;     // == 0: finite solution found;
+                 // == +1 objective funtion unbound; == -1: no solution
+  int *izrov,*iposv;
+
+  mprfloat **LiPM; // the matrix (of size [m+2, n+1])
+
+  /** #rows should be >= m+2, #cols >= n+1
+   */
+  simplex( int rows, int cols );
+  ~simplex();
+
+  BOOLEAN mapFromMatrix( matrix m );
+  matrix mapToMatrix( matrix m );
+  intvec * posvToIV();
+  intvec * zrovToIV();
+
+  void compute();
+
+private:
+  simplex( const simplex & );
+  void simp1( mprfloat **a, int mm, int ll[], int nll, int iabf, int *kp, mprfloat *bmax );
+  void simp2( mprfloat **a, int n, int l2[], int nl2, int *ip, int kp, mprfloat *q1 );
+  void simp3( mprfloat **a, int i1, int k1, int ip, int kp );
+
+  int LiPM_cols,LiPM_rows;
+};
+
+//<-
+
+#endif MPR_NUMERIC_H
+
+// local Variables: ***
+// folded-file: t ***
+// compile-command-1: "make installg" ***
+// compile-command-2: "make install" ***
+// End: ***
Index: kernel/multicnt.cc
===================================================================
--- kernel/multicnt.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/multicnt.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,245 @@
+// ----------------------------------------------------------------------------
+//  multicnt.cc
+//  begin of file
+//  Stephan Endrass, endrass@mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#define MULTICNT_CC
+
+#include "mod2.h"
+
+#ifdef HAVE_SPECTRUM
+
+#include <stdlib.h>
+
+#ifdef  MULTICNT_PRINT
+#include <iostream.h>
+#ifndef  MULTICNT_IOSTREAM
+#include <stdio.h>
+#endif
+#endif
+
+#include "multicnt.h"
+
+// ----------------------------------------------------------------------------
+//  allocate counter memory
+// ----------------------------------------------------------------------------
+
+void    multiCnt::copy_new( int n )
+{
+    if( n > 0 )
+    {
+        cnt = new int[n];
+
+        #ifndef NDEBUG
+        if( cnt == (int*)NULL )
+        {
+            #ifdef MULTICNT_PRINT
+            #ifdef MULTICNT_IOSTREAM
+                cerr << "multiCnt::copy_new(" << n << ")" << endl;
+                cerr << "    returned ZERO!!!" << endl;
+                cerr << "    exit..." << endl;
+            #else
+                fprintf( stderr,"multiCnt::copy_new( %d )\n",n );
+                fprintf( stderr,"    returned ZERO!!!\n" );
+                fprintf( stderr,"    exit...\n" );
+            #endif
+            #endif
+
+            exit( 1 );
+        }
+        #endif
+    }
+    else if( n == 0 )
+    {
+        cnt = (int*)NULL;
+    }
+    else
+    {
+        #ifdef MULTICNT_PRINT
+        #ifdef MULTICNT_IOSTREAM
+            cerr << "multiCnt::copy_new(" << n << ")" << endl;
+            cerr << "    exit..." << endl;
+        #else
+            fprintf( stderr,"multiCnt::copy_new( %d )\n",n );
+            fprintf( stderr,"    exit...\n" );
+        #endif
+        #endif
+
+        exit( 1 );
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  delete counter memory
+// ----------------------------------------------------------------------------
+
+void    multiCnt::copy_delete( void )
+{
+    if( N>0 && cnt!=(int*)NULL ) delete [] cnt;
+    copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  copy a counter
+// ----------------------------------------------------------------------------
+
+void multiCnt::copy_deep( const multiCnt &C )
+{
+    copy_new( C.N );
+
+    last_inc = C.last_inc;
+    N        = C.N;
+
+    for( int i=0; i<N; i++ )
+    {
+        cnt[i] = C.cnt[i];
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  set all counter entries to c
+// ----------------------------------------------------------------------------
+
+void multiCnt::set( int c )
+{
+    for( int i=0; i<N; i++ ) cnt[i]=c;
+}
+
+
+// ----------------------------------------------------------------------------
+//  n entries zero init constructor
+// ----------------------------------------------------------------------------
+
+multiCnt::multiCnt( int n ) :
+    last_inc( 0 )
+{
+    copy_new( n );
+    N = n;
+    set( 0 );
+}
+
+// ----------------------------------------------------------------------------
+//  n entries c init constructor
+// ----------------------------------------------------------------------------
+
+multiCnt::multiCnt( int n,int c ) :
+    last_inc( 0 )
+{
+    copy_new( n );
+    N = n;
+    set( c );
+}
+
+// ----------------------------------------------------------------------------
+//  n entries c* init constructor
+// ----------------------------------------------------------------------------
+
+multiCnt::multiCnt( int n,int *c ) :
+    last_inc( 0 )
+{
+    copy_new( n );
+    N = n;
+    for( int i=0; i<N; i++ ) cnt[i] = c[i];
+}
+
+// ----------------------------------------------------------------------------
+//  increment the counter
+// ----------------------------------------------------------------------------
+
+void multiCnt::inc( void )
+{
+    cnt[0]++;
+    last_inc=0;
+}
+
+// ----------------------------------------------------------------------------
+//  decrement the counter
+// ----------------------------------------------------------------------------
+
+/*
+void multiCnt::dec( void )
+{
+    cnt[0]--;
+    last_inc=0;
+}
+*/
+
+// ----------------------------------------------------------------------------
+//  increment the counter and carry over
+// ----------------------------------------------------------------------------
+
+void multiCnt::inc_carry( void )
+{
+    for( int i=0; i<=last_inc; i++ ) cnt[i] = 0;
+    last_inc++;
+    cnt[last_inc]++;
+}
+
+// ----------------------------------------------------------------------------
+//  decrement the counter and carry over
+// ----------------------------------------------------------------------------
+
+/*
+void multiCnt::dec_carry( void )
+{
+    for( int i=0; i<=last_inc; i++ ) cnt[i] = 0;
+    last_inc++;
+    cnt[last_inc]--;
+}
+*/
+
+// ----------------------------------------------------------------------------
+//  increment the counter and carry over automatic
+// ----------------------------------------------------------------------------
+
+int  multiCnt::inc( int carry )
+{
+    if( carry==FALSE )
+    {
+        inc( );
+    }
+    else
+    {
+        if( last_inc==N-1 )
+        {
+            return  FALSE;
+        }
+
+        inc_carry( );
+    }
+
+    return  TRUE;
+}
+
+// ----------------------------------------------------------------------------
+//  decrement the counter and carry over automatic
+// ----------------------------------------------------------------------------
+
+/*
+int  multiCnt::dec( int carry )
+{
+    if( carry==FALSE )
+    {
+        dec( );
+    }
+    else
+    {
+        if( last_inc==N-1 )
+        {
+            return  FALSE;
+        }
+
+        dec_carry( );
+    }
+
+    return  TRUE;
+}
+*/
+
+#endif /* HAVE_SPECTRUM */
+// ----------------------------------------------------------------------------
+//  multicnt.cc
+//  end of file
+// ----------------------------------------------------------------------------
Index: kernel/multicnt.h
===================================================================
--- kernel/multicnt.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/multicnt.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,83 @@
+// ----------------------------------------------------------------------------
+//  multicnt.h
+//  begin of file
+//  Stephan Endrass, endrass@mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+//  Description: the class multiCnt is a general multi purpose counter.
+//  The counter holds an array  cnt  of  N  integers.
+//  The integer  last_inc  holds the index of the last incremented entry.
+// ----------------------------------------------------------------------------
+
+#ifndef MULTICNT_H
+#define MULTICNT_H
+
+class multiCnt
+{
+public:
+
+    int *cnt;
+    int N;
+    int last_inc;
+
+    multiCnt( );
+    multiCnt( int );
+    multiCnt( int,int );
+    multiCnt( int,int* );
+    multiCnt( const multiCnt& );
+
+    void    copy_zero   ( void );
+    void    copy_new    ( int );
+    void    copy_delete ( void );
+    void    copy_shallow( multiCnt& );
+    void    copy_deep   ( const multiCnt& );
+
+    void    set( int );
+
+    void    inc      ( void );
+    void    inc_carry( void );
+    int     inc      ( int );
+    //void    dec      ( void );
+    //void    dec_carry( void );
+    //int     dec      ( int );
+};
+
+// ----------------------------------------------------------------------------
+//  zero init
+// ----------------------------------------------------------------------------
+
+inline  void    multiCnt::copy_zero( void )
+{
+    cnt      = (int*)NULL;
+    N        = 0;
+    last_inc = 0;
+}
+
+// ----------------------------------------------------------------------------
+//  copy a counter by reference
+// ----------------------------------------------------------------------------
+
+inline  void multiCnt::copy_shallow( multiCnt &C )
+{
+    cnt      = C.cnt;
+    N        = C.N;
+    last_inc = C.last_inc;
+}
+
+// ----------------------------------------------------------------------------
+//  zero constructor
+// ----------------------------------------------------------------------------
+
+inline multiCnt::multiCnt( )
+{
+    copy_zero( );
+}
+
+#endif /* MULTICNT_H */
+
+// ----------------------------------------------------------------------------
+//  multicnt.h
+//  end of file
+// ----------------------------------------------------------------------------
Index: kernel/npolygon.cc
===================================================================
--- kernel/npolygon.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/npolygon.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,671 @@
+// ----------------------------------------------------------------------------
+//  npolygon.cc
+//  begin of file
+//  Stephan Endrass, endrass@mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#define  NPOLYGON_CC
+
+#include "mod2.h"
+
+#ifdef HAVE_SPECTRUM
+
+#ifdef   NPOLYGON_PRINT
+#include <iostream.h>
+#ifndef   NPOLYGON_IOSTREAM
+#include <stdio.h>
+#endif
+#endif
+
+#include "polys.h"
+#include "GMPrat.h"
+#include "kmatrix.h"
+#include "npolygon.h"
+
+// ----------------------------------------------------------------------------
+//  Allocate memory for a linear form of  k  terms
+// ----------------------------------------------------------------------------
+
+void    linearForm::copy_new( int k )
+{
+  if( k > 0 )
+  {
+    c = new Rational[k];
+
+    #ifndef NBDEBUG
+    if( c == (Rational*)NULL )
+    {
+      #ifdef  NPOLYGON_PRINT
+      #ifdef  NPOLYGON_IOSTREAM
+        cerr <<
+        "void linearForm::copy_new( int k ): no memory left ...\n" ;
+      #else
+        fprintf( stderr,
+        "void linearForm::copy_new( int k ): no memory left ...\n");
+      #endif
+      #endif
+      HALT();
+    }
+    #endif
+  }
+  else if( k == 0 )
+  {
+    c = (Rational*)NULL;
+  }
+  else if( k < 0 )
+  {
+    #ifdef  NPOLYGON_PRINT
+    #ifdef  NPOLYGON_IOSTREAM
+      cerr <<
+      "void linearForm::copy_new( int k ): k < 0 ...\n";
+    #else
+      fprintf( stderr,
+      "void linearForm::copy_new( int k ): k < 0 ...\n" );
+    #endif
+    #endif
+
+    HALT();
+  }
+}
+
+// ----------------------------------------------------------------------------
+//  Delete the memory of a linear form
+// ----------------------------------------------------------------------------
+
+void    linearForm::copy_delete( void )
+{
+  if( c != (Rational*)NULL && N > 0 )
+    delete [] c;
+  copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  Initialize deep from another linear form
+// ----------------------------------------------------------------------------
+
+void    linearForm::copy_deep( const linearForm &l )
+{
+  copy_new( l.N );
+  for( int i=l.N-1; i>=0; i-- )
+  {
+    c[i] = l.c[i];
+  }
+  N = l.N;
+}
+
+// ----------------------------------------------------------------------------
+//  Copy constructor
+// ----------------------------------------------------------------------------
+
+linearForm::linearForm( const linearForm &l )
+{
+  copy_deep( l );
+}
+
+// ----------------------------------------------------------------------------
+//  Destructor
+// ----------------------------------------------------------------------------
+
+linearForm::~linearForm( )
+{
+  copy_delete( );
+}
+
+// ----------------------------------------------------------------------------
+//  Define `=` to be a deep copy
+// ----------------------------------------------------------------------------
+
+linearForm & linearForm::operator = ( const linearForm &l )
+{
+  copy_delete( );
+  copy_deep( l );
+
+  return *this;
+}
+
+// ----------------------------------------------------------------------------
+//  ostream for linear form
+// ----------------------------------------------------------------------------
+
+#ifdef  NPOLYGON_PRINT
+
+ostream & operator << ( ostream &s,const linearForm &l )
+{
+  for( int i=0; i<l.N; i++ )
+  {
+    if( l.c[i] != (Rational)0 )
+    {
+      if( i > 0 && l.c[i] >= (Rational)0 )
+      {
+        #ifdef NPOLYGON_IOSTREAM
+          s << "+";
+        #else
+          fprintf( stdout,"+" );
+        #endif
+      }
+
+      s << l.c[i];
+
+      #ifdef NPOLYGON_IOSTREAM
+        s << "*x" << i+1;
+      #else
+        fprintf( stdout,"*x%d",i+1 );
+      #endif
+    }
+  }
+  return s;
+}
+
+#endif
+
+// ----------------------------------------------------------------------------
+//  Equality of linear forms
+// ----------------------------------------------------------------------------
+
+int     operator == ( const linearForm &l1,const linearForm &l2 )
+{
+  if( l1.N!=l2.N )
+    return  FALSE;
+  for( int i=l1.N-1; i >=0 ; i-- )
+  {
+    if( l1.c[i]!=l2.c[i] )
+      return  FALSE;
+  }
+  return  TRUE;
+}
+
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a monomial
+// ----------------------------------------------------------------------------
+
+Rational linearForm::weight( poly m ) const
+{
+  Rational ret=(Rational)0;
+
+  for( int i=0,j=1; i<N; i++,j++ )
+  {
+    ret += c[i]*(Rational)pGetExp( m,j );
+  }
+
+  return ret;
+}
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a polynomial
+// ----------------------------------------------------------------------------
+
+Rational linearForm::pweight( poly m ) const
+{
+  if( m==(poly)NULL )
+    return  (Rational)0;
+
+  Rational    ret = weight( m );
+  Rational    tmp;
+
+  for( m=pNext(m); m!=(poly)NULL; pIter(m) )
+  {
+    tmp = weight( m );
+    if( tmp<ret )
+    {
+      ret = tmp;
+    }
+  }
+
+  return ret;
+}
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a monomial shifted by the product of the variables
+// ----------------------------------------------------------------------------
+
+Rational linearForm::weight_shift( poly m ) const
+{
+  Rational ret=(Rational)0;
+
+  for( int i=0,j=1; i<N; i++,j++ )
+  {
+    ret += c[i]*(Rational)( pGetExp( m,j ) + 1 );
+  }
+
+  return ret;
+}
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a monomial (forgetting the first variable)
+// ----------------------------------------------------------------------------
+
+Rational linearForm::weight1( poly m ) const
+{
+  Rational ret=(Rational)0;
+
+  for( int i=0,j=2; i<N; i++,j++ )
+  {
+    ret += c[i]*(Rational)pGetExp( m,j );
+  }
+
+  return ret;
+}
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a monomial shifted by the product of the variables
+//  (forgetting the first variable)
+// ----------------------------------------------------------------------------
+
+Rational linearForm::weight_shift1( poly m ) const
+{
+  Rational ret=(Rational)0;
+
+  for( int i=0,j=2; i<N; i++,j++ )
+  {
+    ret += c[i]*(Rational)( pGetExp( m,j ) + 1 );
+  }
+
+  return ret;
+}
+
+
+// ----------------------------------------------------------------------------
+//  Test if all coefficients of a linear form are positive
+// ----------------------------------------------------------------------------
+
+int linearForm::positive( void )
+{
+  for( int i=0; i<N; i++ )
+  {
+    if( c[i] <= (Rational)0 )
+    {
+      return FALSE;
+    }
+  }
+  return  TRUE;
+}
+
+
+// ----------------------------------------------------------------------------
+//  Allocate memory for a newton polygon of  k  linear forms
+// ----------------------------------------------------------------------------
+
+void    newtonPolygon::copy_new( int k )
+{
+  if( k > 0 )
+  {
+    l = new linearForm[k];
+
+    #ifndef NDEBUG
+      if( l == (linearForm*)NULL )
+      {
+        #ifdef  NPOLYGON_PRINT
+          #ifdef  NPOLYGON_IOSTREAM
+            cerr <<
+            "void newtonPolygon::copy_new( int k ): no memory left ...\n";
+          #else
+            fprintf( stderr,
+            "void newtonPolygon::copy_new( int k ): no memory left ...\n" );
+          #endif
+        #endif
+
+        HALT();
+      }
+    #endif
+  }
+  else if( k == 0 )
+  {
+    l = (linearForm*)NULL;
+  }
+  else if( k < 0 )
+  {
+    #ifdef  NPOLYGON_PRINT
+      #ifdef  NPOLYGON_IOSTREAM
+        cerr << "void newtonPolygon::copy_new( int k ): k < 0 ...\n";
+      #else
+        fprintf( stderr,
+        "void newtonPolygon::copy_new( int k ): k < 0 ...\n" );
+      #endif
+    #endif
+
+    HALT();
+  }
+}
+
+// ----------------------------------------------------------------------------
+//  Delete the memory of a Newton polygon
+// ----------------------------------------------------------------------------
+
+void    newtonPolygon::copy_delete( void )
+{
+  if( l != (linearForm*)NULL && N > 0 )
+    delete [] l;
+  copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  Initialize deep from another Newton polygon
+// ----------------------------------------------------------------------------
+
+void    newtonPolygon::copy_deep( const newtonPolygon &np )
+{
+  copy_new( np.N );
+  for( int i=0; i<np.N; i++ )
+  {
+    l[i] = np.l[i];
+  }
+  N = np.N;
+}
+
+// ----------------------------------------------------------------------------
+//  Copy constructor
+// ----------------------------------------------------------------------------
+
+newtonPolygon::newtonPolygon( const newtonPolygon &np )
+{
+  copy_deep( np );
+}
+
+// ----------------------------------------------------------------------------
+//  Destructor
+// ----------------------------------------------------------------------------
+
+newtonPolygon::~newtonPolygon( )
+{
+  copy_delete( );
+}
+
+// ----------------------------------------------------------------------------
+//  We define `=` to be a deep copy
+// ----------------------------------------------------------------------------
+
+newtonPolygon & newtonPolygon::operator = ( const newtonPolygon &np )
+{
+  copy_delete( );
+  copy_deep( np );
+
+  return *this;
+}
+
+// ----------------------------------------------------------------------------
+//  Initialize a Newton polygon from a polynomial
+// ----------------------------------------------------------------------------
+
+newtonPolygon::newtonPolygon( poly f )
+{
+  copy_zero( );
+
+  int *r=new int[pVariables];
+  poly *m=new poly[pVariables];
+
+
+  KMatrix<Rational> mat( pVariables,pVariables+1 );
+
+  int i,j,stop=FALSE;
+  linearForm sol;
+
+  // ---------------
+  //  init counters
+  // ---------------
+
+  for( i=0; i<pVariables; i++ )
+  {
+    r[i] = i;
+  }
+
+  m[0] = f;
+
+  for( i=1; i<pVariables; i++ )
+  {
+    m[i] = pNext(m[i-1]);
+  }
+
+  // -----------------------------
+  //  find faces (= linear forms)
+  // -----------------------------
+
+  do
+  {
+    // ---------------------------------------------------
+    //  test if monomials p.m[r[0]]m,...,p.m[r[p.vars-1]]
+    //  are linearely independent
+    // ---------------------------------------------------
+
+    for( i=0; i<pVariables; i++ )
+    {
+      for( j=0; j<pVariables; j++ )
+      {
+        //    mat.set( i,j,pGetExp( m[r[i]],j+1 ) );
+        mat.set( i,j,pGetExp( m[i],j+1 ) );
+      }
+      mat.set( i,j,1 );
+    }
+
+    if( mat.solve( &(sol.c),&(sol.N) ) == pVariables )
+    {
+      // ---------------------------------
+      //  check if linearForm is positive
+      //  check if linearForm is extremal
+      // ---------------------------------
+
+      if( sol.positive( ) && sol.pweight( f ) >= (Rational)1 )
+      {
+        // ----------------------------------
+        //  this is a face or the polyhedron
+        // ----------------------------------
+
+        add_linearForm( sol );
+        sol.c = (Rational*)NULL;
+        sol.N = 0;
+      }
+    }
+
+    // --------------------
+    //  increment counters
+    // --------------------
+
+    for( i=1; r[i-1] + 1 == r[i] && i < pVariables; i++ );
+
+    for( j=0; j<i-1; j++ )
+    {
+      r[j]=j;
+    }
+
+    if( i>1 )
+    {
+      m[0]=f;
+      for( j=1; j<i-1; j++ )
+      {
+        m[j]=pNext(m[j-1]);
+      }
+    }
+    r[i-1]++;
+    m[i-1]=pNext(m[i-1]);
+
+    if( m[pVariables-1] == (poly)NULL )
+    {
+      stop = TRUE;
+    }
+  } while( stop == FALSE );
+}
+
+#ifdef  NPOLYGON_PRINT
+
+ostream & operator << ( ostream &s,const newtonPolygon &a )
+{
+  #ifdef NPOLYGON_IOSTREAM
+    s << "Newton polygon:" << endl;
+  #else
+    fprintf( stdout,"Newton polygon:\n" );
+  #endif
+
+  for( int i=0; i<a.N; i++ )
+  {
+    s << a.l[i];
+
+    #ifdef NPOLYGON_IOSTREAM
+      s << endl;
+    #else
+      fprintf( stdout,"\n" );
+    #endif
+  }
+
+  return s;
+}
+
+#endif
+
+// ----------------------------------------------------------------------------
+//  Add a face to the newton polygon
+// ----------------------------------------------------------------------------
+
+void    newtonPolygon::add_linearForm( const linearForm &l0 )
+{
+  int           i;
+  newtonPolygon np;
+
+  // -------------------------------------
+  //  test if linear form is already here
+  // -------------------------------------
+
+  for( i=0; i<N; i++ )
+  {
+    if( l0==l[i] )
+    {
+      return;
+    }
+  }
+
+  np.copy_new( N+1 );
+  np.N = N+1;
+
+  for( i=0; i<N; i++ )
+  {
+    np.l[i].copy_shallow( l[i] );
+    l[i].copy_zero( );
+  }
+
+  np.l[N] = l0;
+
+  copy_delete( );
+  copy_shallow( np );
+  np.copy_zero( );
+
+  return;
+}
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a monomial
+// ----------------------------------------------------------------------------
+
+Rational  newtonPolygon::weight( poly m ) const
+{
+  Rational ret = l[0].weight( m );
+  Rational tmp;
+
+  for( int i=1; i<N; i++ )
+  {
+    tmp = l[i].weight( m );
+
+    if( tmp < ret )
+    {
+      ret = tmp;
+    }
+  }
+  return ret;
+}
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a monomial shifted by the product of the variables
+// ----------------------------------------------------------------------------
+
+Rational  newtonPolygon::weight_shift( poly m ) const
+{
+  Rational ret = l[0].weight_shift( m );
+  Rational tmp;
+
+  for( int i=1; i<N; i++ )
+  {
+    tmp = l[i].weight_shift( m );
+
+    if( tmp < ret )
+    {
+      ret = tmp;
+    }
+  }
+  return ret;
+}
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a monomial (forgetting the first variable)
+// ----------------------------------------------------------------------------
+
+Rational  newtonPolygon::weight1( poly m ) const
+{
+  Rational ret = l[0].weight1( m );
+  Rational tmp;
+
+  for( int i=1; i<N; i++ )
+  {
+    tmp = l[i].weight1( m );
+
+    if( tmp < ret )
+    {
+      ret = tmp;
+    }
+  }
+  return ret;
+}
+
+// ----------------------------------------------------------------------------
+//  Newton weight of a monomial shifted by the product of the variables
+//  (forgetting the first variable)
+// ----------------------------------------------------------------------------
+
+Rational  newtonPolygon::weight_shift1( poly m ) const
+{
+  Rational ret = l[0].weight_shift1( m );
+  Rational tmp;
+
+  for( int i=1; i<N; i++ )
+  {
+    tmp = l[i].weight_shift1( m );
+
+    if( tmp < ret )
+    {
+      ret = tmp;
+    }
+  }
+  return ret;
+}
+
+/*
+// ----------------------------------------------------------------------------
+//  Chcek if the polynomial belonging to the Newton polygon
+//  is semiquasihomogeneous (sqh)
+// ----------------------------------------------------------------------------
+
+int     newtonPolygon::is_sqh( void ) const
+{
+  return ( N==1 ? TRUE : FALSE );
+}
+
+// ----------------------------------------------------------------------------
+//  If the polynomial belonging to the Newton polygon is sqh,
+//  return its weights vector
+// ----------------------------------------------------------------------------
+
+Rational*   newtonPolygon::sqh_weights( void ) const
+{
+  return ( N==1 ? l[0].c : (Rational*)NULL );
+}
+
+int    newtonPolygon::sqh_N( void ) const
+{
+  return ( N==1 ? l[0].N : 0 );
+}
+*/
+
+#endif /* HAVE_SPECTRUM */
+// ----------------------------------------------------------------------------
+//  npolygon.cc
+//  end of file
+// ----------------------------------------------------------------------------
+
Index: kernel/npolygon.h
===================================================================
--- kernel/npolygon.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/npolygon.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,175 @@
+// ----------------------------------------------------------------------------
+//  npolygon.h
+//  begin of file
+//  Stephan Endrass, endrass@mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#ifndef NPOLYGON_H
+#define NPOLYGON_H
+
+#include "GMPrat.h"
+
+// ----------------------------------------------------------------------------
+//  Class representing a linear form QQ^N-->QQ
+// ----------------------------------------------------------------------------
+
+class linearForm
+{
+
+private:
+
+    Rational    *c;                   // the coefficients
+    int         N;                    // number of coefficients
+
+public:
+
+    linearForm( );
+    linearForm( const linearForm& );
+    ~linearForm( );
+
+    linearForm & operator = ( const linearForm& );
+
+    friend  int     operator == ( const linearForm&,const linearForm& );
+
+    void        copy_new     ( int );
+    void        copy_delete  ( void );
+    void        copy_zero    ( void );
+    void        copy_shallow ( linearForm& );
+    void        copy_deep    ( const linearForm& );
+
+    Rational    weight       ( poly ) const;
+    Rational    weight_shift ( poly ) const;
+    Rational    weight1      ( poly ) const;
+    Rational    weight_shift1( poly ) const;
+
+    Rational    pweight      ( poly ) const;
+
+    int         positive     ( void );
+
+    #ifdef  NPOLYGON_PRINT
+        friend ostream & operator << ( ostream&,const linearForm& );
+    #endif
+
+    friend class newtonPolygon;
+};
+
+// ----------------------------------------------------------------------------
+//  Class representing a Newton polygon
+// ----------------------------------------------------------------------------
+
+class newtonPolygon
+{
+
+private:
+
+    linearForm  *l;                   // the linear forms
+    int         N;                    // number of linear forms
+
+public:
+
+    newtonPolygon( );
+    newtonPolygon( const newtonPolygon& );
+    newtonPolygon( poly );
+    ~newtonPolygon( );
+
+    newtonPolygon & operator = ( const newtonPolygon& );
+
+
+    void        copy_new    ( int );
+    void        copy_delete ( void );
+    void        copy_zero   ( void );
+    void        copy_shallow( newtonPolygon& );
+    void        copy_deep   ( const newtonPolygon& );
+
+    void        add_linearForm( const linearForm& );
+
+    Rational    weight       ( poly ) const;
+    Rational    weight_shift ( poly ) const;
+    Rational    weight1      ( poly ) const;
+    Rational    weight_shift1( poly ) const;
+
+    //int         is_sqh     ( void ) const;
+    //Rational*   sqh_weights( void ) const;
+    //int         sqh_N      ( void ) const;
+
+    #ifdef  NPOLYGON_PRINT
+        friend ostream & operator << ( ostream&,const newtonPolygon&  );
+    #endif
+};
+
+// ---------------------------------------
+//  inline functions for class linearForm
+// ---------------------------------------
+
+// ----------------------------------------------------------------------------
+//  Initialize with zero
+// ----------------------------------------------------------------------------
+
+inline  void    linearForm::copy_zero( void )
+{
+    c = (Rational*)NULL;
+    N = 0;
+}
+
+// ----------------------------------------------------------------------------
+//  Initialize shallow from another linear form
+// ----------------------------------------------------------------------------
+
+inline  void    linearForm::copy_shallow( linearForm &l )
+{
+    c = l.c;
+    N = l.N;
+}
+
+
+// ----------------------------------------------------------------------------
+//  Zero constructor
+// ----------------------------------------------------------------------------
+
+inline  linearForm::linearForm( )
+{
+    copy_zero( );
+}
+
+
+// ------------------------------------------
+//  inline functions for class newtonPolygon
+// ------------------------------------------
+
+// ----------------------------------------------------------------------------
+//  Initialize with zero
+// ----------------------------------------------------------------------------
+
+inline  void    newtonPolygon::copy_zero( void )
+{
+    l = (linearForm*)NULL;
+    N = 0;
+}
+
+// ----------------------------------------------------------------------------
+//  Initialize shallow from another Newton polygon
+// ----------------------------------------------------------------------------
+
+inline  void    newtonPolygon::copy_shallow( newtonPolygon &np )
+{
+    l = np.l;
+    N = np.N;
+}
+
+
+// ----------------------------------------------------------------------------
+//  Zero constructor
+// ----------------------------------------------------------------------------
+
+inline newtonPolygon::newtonPolygon( )
+{
+    copy_zero( );
+}
+
+#endif /* NPOLYGON_H */
+
+// ----------------------------------------------------------------------------
+//  npolygon.h
+//  end of file
+// ----------------------------------------------------------------------------
Index: kernel/numbers.cc
===================================================================
--- kernel/numbers.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/numbers.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,544 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/* $Id: numbers.cc,v 1.1.1.1 2003-10-06 12:15:58 Singular Exp $ */
+
+/*
+* ABSTRACT: interface to coefficient aritmetics
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include "mod2.h"
+#include "structs.h"
+#include "febase.h"
+#include "kstd1.h"
+#include "numbers.h"
+#include "longrat.h"
+#include "longalg.h"
+#include "modulop.h"
+#include "gnumpfl.h"
+#include "gnumpc.h"
+#include "ring.h"
+#include "ffields.h"
+#include "shortfl.h"
+
+//static int characteristic = 0;
+extern int IsPrime(int p);
+
+void   (*nNew)(number *a);
+number (*nInit)(int i);
+number (*nPar)(int i);
+int    (*nParDeg)(number n);
+int    (*nSize)(number n);
+int    (*nInt)(number &n);
+numberfunc nMult, nSub, nAdd, nDiv, nIntDiv, nIntMod, nExactDiv;
+number (*nNeg)(number a);
+number (*nInvers)(number a);
+void   (*nNormalize)(number &a);
+number (*nCopy)(number a);
+number (*nRePart)(number a);
+number (*nImPart)(number a);
+BOOLEAN (*nGreater)(number a,number b);
+BOOLEAN (*nEqual)(number a,number b);
+BOOLEAN (*nIsZero)(number a);
+BOOLEAN (*nIsOne)(number a);
+BOOLEAN (*nIsMOne)(number a);
+BOOLEAN (*nGreaterZero)(number a);
+void    (*nWrite)(number &a);
+char *  (*nRead)(char *s,number *a);
+void    (*nPower)(number a, int i, number * result);
+number  (*nGcd)(number a, number b, const ring r);
+number  (*nLcm)(number a, number b, const ring r);
+char * (*nName)(number n);
+void   (*n__Delete)(number *a, const ring r);
+
+/*0 implementation*/
+number nNULL; /* the 0 as constant */
+
+
+n_Procs_s *cf_root=NULL;
+
+void   nDummy1(number* d) { *d=NULL; }
+void   ndDelete(number* d, const ring r) { *d=NULL; }
+void   ndInpMult(number &a, number b, const ring r)
+{
+  number n=n_Mult(a,b,r);
+  n_Delete(&a,r);
+  a=n;
+}
+
+#ifdef LDEBUG
+void   nDBDummy1(number* d,char *f, int l) { *d=NULL; }
+#endif
+
+void   nDummy2(number& d) { }
+
+char * ndName(number n) { return NULL; }
+
+number ndPar(int i) { return nInit(0); }
+
+number ndReturn0(number n) { return nInit(0); }
+
+int    ndParDeg(number n) { return 0; }
+
+number ndGcd(number a, number b, const ring r) { return r->cf->nInit(1); }
+
+number ndIntMod(number a, number b) { return nInit(0); }
+
+number ndGetDenom(number &n, const ring r) { return n_Init(1,r); }
+
+int ndSize(number a) { return (int)nIsZero(a)==FALSE; }
+
+number ndCopy(number a) { return a; }
+number nd_Copy(number a,const ring r) { return r->cf->nCopy(a); }
+
+/*2
+* init operations for characteristic c (complete==TRUE)
+* init nDelete    for characteristic c (complete==FALSE)
+*/
+void nSetChar(ring r)
+{
+  int c=rInternalChar(r);
+
+  n__Delete= r->cf->cfDelete;
+  if (rField_is_Extension(r))
+  {
+    naSetChar(c,r);
+  }
+  else if (rField_is_Zp(r))
+  /*----------------------char. p----------------*/
+  {
+    npSetChar(c, r);
+  }
+  /* -------------- GF(p^m) -----------------------*/
+  else if (rField_is_GF(r))
+  {
+    nfSetChar(c,r->parameter);
+  }
+  /* -------------- R -----------------------*/
+  //if (c==(-1))
+  else if (rField_is_R(r))
+  {
+  }
+  /* -------------- long R -----------------------*/
+  /* -------------- long C -----------------------*/
+  else if ((rField_is_long_R(r))
+  || (rField_is_long_C(r)))
+  {
+    setGMPFloatDigits(r->float_len,r->float_len2);
+  }
+#ifdef TEST
+  /* -------------- R -----------------------*/
+  //if (c==(-1))
+  else if (!rField_is_R(r) && !rField_is_Q(r))
+  {
+    WerrorS("unknown field");
+  }
+#endif
+  nNew   = r->cf->nNew;
+  nNormalize=r->cf->nNormalize;
+  nInit  = r->cf->nInit;
+  nPar   = r->cf->nPar;
+  nParDeg= r->cf->nParDeg;
+  nInt   = r->cf->nInt;
+  nAdd   = r->cf->nAdd;
+  nSub   = r->cf->nSub;
+  nMult  = r->cf->nMult;
+  nDiv   = r->cf->nDiv;
+  nExactDiv= r->cf->nExactDiv;
+  nIntDiv= r->cf->nIntDiv;
+  nIntMod= r->cf->nIntMod;
+  nNeg   = r->cf->nNeg;
+  nInvers= r->cf->nInvers;
+  nCopy  = r->cf->nCopy;
+  nGreater = r->cf->nGreater;
+  nEqual = r->cf->nEqual;
+  nIsZero = r->cf->nIsZero;
+  nIsOne = r->cf->nIsOne;
+  nIsMOne = r->cf->nIsMOne;
+  nGreaterZero = r->cf->nGreaterZero;
+  nWrite = r->cf->nWrite;
+  nRead = r->cf->nRead;
+  nPower = r->cf->nPower;
+  nGcd  = r->cf->nGcd;
+  nLcm  = r->cf->nLcm;
+  nName= r->cf->nName;
+  nSize  = r->cf->nSize;
+  nRePart = r->cf->nRePart;
+  nImPart = r->cf->nImPart;
+  if (!errorreported) nNULL=r->cf->nNULL;
+}
+
+/*2
+* init operations for ring r
+*/
+void nInitChar(ring r)
+{
+  int c=rInternalChar(r);
+  n_coeffType t=rFieldType(r);
+
+  if (rField_is_Extension(r))
+  {
+    if (r->algring==NULL)
+    {
+      int ch=-c;
+      if (c==1) ch=0;
+      r->algring=(ring) rDefault(ch,r->P,r->parameter);
+      //r->algring->ShortOut=r->ShortOut;
+      // includes: nInitChar(r->algring);
+    }
+  }
+
+  n_Procs_s *n=cf_root;
+  while((n!=NULL)
+    && ((n->nChar!=c) || (n->type!=t)))
+      n=n->next;
+  if (n==NULL)
+  {
+    n=(n_Procs_s*)omAlloc0(sizeof(n_Procs_s));
+    n->next=cf_root;
+    n->ref=1;
+    n->nChar=c;
+    n->type=t;
+    cf_root=n;
+  }
+  else if ((n->nChar==c) && (n->type==t))
+  {
+    n->ref++;
+    r->cf=n;
+    return;
+  }
+  else
+  {
+    WerrorS("nInitChar failed");
+    return;
+  }
+  r->cf=n;
+  n->nChar = c;
+  n->nPar  = ndPar;
+  n->nParDeg=ndParDeg;
+  n->nSize = ndSize;
+  n->n_GetDenom= ndGetDenom;
+  n->nName =  ndName;
+  n->nImPart=ndReturn0;
+  n->cfDelete= ndDelete;
+  n->nNew=nDummy1;
+  n->nInpMult=ndInpMult;
+  n->cfCopy=nd_Copy;
+  n->nIntMod=ndIntMod; /* dummy !! */
+  n->nNormalize=nDummy2;
+  n->nGcd  = ndGcd;
+  n->nLcm  = ndGcd; /* tricky, isn't it ?*/
+  if (rField_is_Extension(r))
+  {
+    //naInitChar(c,TRUE,r);
+    n->cfDelete = naDelete;
+    n-> nNew       = naNew;
+    n-> nNormalize = naNormalize;
+    n->nInit       = naInit;
+    n->nPar        = naPar;
+    n->nParDeg     = naParDeg;
+    n->nInt        = naInt;
+    n->nAdd        = naAdd;
+    n->nSub        = naSub;
+    n->nMult       = naMult;
+    n->nDiv        = naDiv;
+    n->nExactDiv   = naDiv;
+    n->nIntDiv     = naIntDiv;
+    n->nNeg        = naNeg;
+    n->nInvers     = naInvers;
+    n->nCopy       = naCopy;
+    n->cfCopy      = na_Copy;
+    n->nGreater    = naGreater;
+    n->nEqual      = naEqual;
+    n->nIsZero     = naIsZero;
+    n->nIsOne      = naIsOne;
+    n->nIsMOne     = naIsMOne;
+    n->nGreaterZero= naGreaterZero;
+    n->nWrite      = naWrite;
+    n->nRead       = naRead;
+    n->nPower      = naPower;
+    n->nGcd        = naGcd;
+    n->nLcm        = naLcm;
+    n->cfSetMap    = naSetMap;
+    n->nName       = naName;
+    n->nSize       = naSize;
+    n->n_GetDenom   = naGetDenom;
+#ifdef LDEBUG
+    //n->nDBTest     = naDBTest;
+#endif
+  }
+  else if (rField_is_Q(r))
+  {
+    n->cfDelete= nlDelete;
+    n->nNew   = nlNew;
+    n->nNormalize=nlNormalize;
+    n->nInit  = nlInit;
+    n->nInt   = nlInt;
+    n->nAdd   = nlAdd;
+    n->nSub   = nlSub;
+    n->nMult  = nlMult;
+    n->nInpMult=nlInpMult;
+    n->nDiv   = nlDiv;
+    n->nExactDiv= nlExactDiv;
+    n->nIntDiv= nlIntDiv;
+    n->nIntMod= nlIntMod;
+    n->nNeg   = nlNeg;
+    n->nInvers= nlInvers;
+    n->nCopy  = nlCopy;
+    n->nGreater = nlGreater;
+    n->nEqual = nlEqual;
+    n->nIsZero = nlIsZero;
+    n->nIsOne = nlIsOne;
+    n->nIsMOne = nlIsMOne;
+    n->nGreaterZero = nlGreaterZero;
+    n->nWrite = nlWrite;
+    n->nRead = nlRead;
+    n->nPower = nlPower;
+    n->nGcd  = nlGcd;
+    n->nLcm  = nlLcm;
+    n->cfSetMap = nlSetMap;
+    n->nSize  = nlSize;
+    n->n_GetDenom = nlGetDenom;
+#ifdef LDEBUG
+    //n->nDBTest=nlDBTest;
+#endif
+  }
+  else if (rField_is_Zp(r))
+  /*----------------------char. p----------------*/
+  {
+    npInitChar(c,r);
+    n->nInit  = npInit;
+    n->nInt   = npInt;
+    n->nAdd   = npAdd;
+    n->nSub   = npSub;
+    n->nMult  = npMult;
+    n->nDiv   = npDiv;
+    n->nExactDiv= npDiv;
+    n->nNeg   = npNeg;
+    n->nInvers= npInvers;
+    n->nCopy  = ndCopy;
+    n->nGreater = npGreater;
+    n->nEqual = npEqual;
+    n->nIsZero = npIsZero;
+    n->nIsOne = npIsOne;
+    n->nIsMOne = npIsMOne;
+    n->nGreaterZero = npGreaterZero;
+    n->nWrite = npWrite;
+    n->nRead = npRead;
+    n->nPower = npPower;
+    n->cfSetMap = npSetMap;
+    /* nName= ndName; */
+    /*nSize  = ndSize;*/
+#ifdef LDEBUG
+    //n->nDBTest=npDBTest;
+#endif
+#ifdef NV_OPS
+    if (c>NV_MAX_PRIME)
+    {
+      n->nMult  = nvMult;
+      n->nDiv   = nvDiv;
+      n->nExactDiv= nvDiv;
+      n->nInvers= nvInvers;
+    }
+#endif
+  }
+  /* -------------- GF(p^m) -----------------------*/
+  else if (rField_is_GF(r))
+  {
+    //nfSetChar(c,r->parameter);
+    n->nInit  = nfInit;
+    n->nPar   = nfPar;
+    n->nParDeg= nfParDeg;
+    n->nInt   = nfInt;
+    n->nAdd   = nfAdd;
+    n->nSub   = nfSub;
+    n->nMult  = nfMult;
+    n->nDiv   = nfDiv;
+    n->nExactDiv= nfDiv;
+    n->nNeg   = nfNeg;
+    n->nInvers= nfInvers;
+    n->nCopy  = ndCopy;
+    n->nGreater = nfGreater;
+    n->nEqual = nfEqual;
+    n->nIsZero = nfIsZero;
+    n->nIsOne = nfIsOne;
+    n->nIsMOne = nfIsMOne;
+    n->nGreaterZero = nfGreaterZero;
+    n->nWrite = nfWrite;
+    n->nRead = nfRead;
+    n->nPower = nfPower;
+    n->cfSetMap = nfSetMap;
+    n->nName= nfName;
+    /*nSize  = ndSize;*/
+#ifdef LDEBUG
+    //n->nDBTest=nfDBTest;
+#endif
+  }
+  /* -------------- R -----------------------*/
+  //if (c==(-1))
+  else if (rField_is_R(r))
+  {
+    n->nInit  = nrInit;
+    n->nInt   = nrInt;
+    n->nAdd   = nrAdd;
+    n->nSub   = nrSub;
+    n->nMult  = nrMult;
+    n->nDiv   = nrDiv;
+    n->nExactDiv= nrDiv;
+    n->nNeg   = nrNeg;
+    n->nInvers= nrInvers;
+    n->nCopy  = ndCopy;
+    n->nGreater = nrGreater;
+    n->nEqual = nrEqual;
+    n->nIsZero = nrIsZero;
+    n->nIsOne = nrIsOne;
+    n->nIsMOne = nrIsMOne;
+    n->nGreaterZero = nrGreaterZero;
+    n->nWrite = nrWrite;
+    n->nRead = nrRead;
+    n->nPower = nrPower;
+    n->cfSetMap=nrSetMap;
+    /* nName= ndName; */
+    /*nSize  = ndSize;*/
+#ifdef LDEBUG
+    //n->nDBTest=nrDBTest;
+#endif
+  }
+  /* -------------- long R -----------------------*/
+  else if (rField_is_long_R(r))
+  {
+    n->cfDelete= ngfDelete;
+    n->nNew=ngfNew;
+    n->nInit  = ngfInit;
+    n->nInt   = ngfInt;
+    n->nAdd   = ngfAdd;
+    n->nSub   = ngfSub;
+    n->nMult  = ngfMult;
+    n->nDiv   = ngfDiv;
+    n->nExactDiv= ngfDiv;
+    n->nNeg   = ngfNeg;
+    n->nInvers= ngfInvers;
+    n->nCopy  = ngfCopy;
+    n->nGreater = ngfGreater;
+    n->nEqual = ngfEqual;
+    n->nIsZero = ngfIsZero;
+    n->nIsOne = ngfIsOne;
+    n->nIsMOne = ngfIsMOne;
+    n->nGreaterZero = ngfGreaterZero;
+    n->nWrite = ngfWrite;
+    n->nRead = ngfRead;
+    n->nPower = ngfPower;
+    n->cfSetMap=ngfSetMap;
+    n->nName= ndName;
+    n->nSize  = ndSize;
+#ifdef LDEBUG
+    //n->nDBTest=ngfDBTest;
+#endif
+  }
+  /* -------------- long C -----------------------*/
+  else if (rField_is_long_C(r))
+  {
+    n->cfDelete= ngcDelete;
+    n->nNew=ngcNew;
+    n->nNormalize=nDummy2;
+    n->nInit  = ngcInit;
+    n->nInt   = ngcInt;
+    n->nAdd   = ngcAdd;
+    n->nSub   = ngcSub;
+    n->nMult  = ngcMult;
+    n->nDiv   = ngcDiv;
+    n->nExactDiv= ngcDiv;
+    n->nNeg   = ngcNeg;
+    n->nInvers= ngcInvers;
+    n->nCopy  = ngcCopy;
+    n->nGreater = ngcGreater;
+    n->nEqual = ngcEqual;
+    n->nIsZero = ngcIsZero;
+    n->nIsOne = ngcIsOne;
+    n->nIsMOne = ngcIsMOne;
+    n->nGreaterZero = ngcGreaterZero;
+    n->nWrite = ngcWrite;
+    n->nRead = ngcRead;
+    n->nPower = ngcPower;
+    n->cfSetMap=ngcSetMap;
+    n->nPar=ngcPar;
+    n->nRePart=ngcRePart;
+    n->nImPart=ngcImPart;
+    /*nSize  = ndSize;*/
+#ifdef LDEBUG
+    //n->nDBTest=ngcDBTest;
+#endif
+  }
+#ifdef TEST
+  else
+  {
+    WerrorS("unknown field");
+  }
+#endif
+  if (!errorreported)
+  {
+    n->nNULL=n->nInit(0);
+    if (n->nRePart==NULL)
+      n->nRePart=n->nCopy;
+    if (n->nIntDiv==NULL)
+      n->nIntDiv=n->nDiv;
+  }
+}
+
+void nKillChar(ring r)
+{
+  if (r!=NULL)
+  {
+    if (r->cf!=NULL)
+    {
+      r->cf->ref--;
+      if (r->cf->ref<=0)
+      {
+        n_Procs_s tmp;
+        n_Procs_s* n=&tmp;
+        tmp.next=cf_root;
+        while((n->next!=NULL) && (n->next!=r->cf)) n=n->next;
+        if (n->next==r->cf)
+        {
+          n->next=n->next->next;
+          if (cf_root==r->cf) cf_root=n->next;
+          r->cf->cfDelete(&(r->cf->nNULL),r);
+          switch(r->cf->type)
+          {
+            case n_Zp:
+                 #ifdef HAVE_DIV_MOD
+		 if (r->cf->npInvTable!=NULL)
+                 omFreeSize( (ADDRESS)r->cf->npInvTable,
+                             r->cf->npPrimeM*sizeof(CARDINAL) );
+                 #else
+		 if (r->cf->npExpTable!=NULL)
+		 {
+                   omFreeSize( (ADDRESS)r->cf->npExpTable,
+                               r->cf->npPrimeM*sizeof(CARDINAL) );
+                   omFreeSize( (ADDRESS)r->cf->npLogTable,
+                               r->cf->npPrimeM*sizeof(CARDINAL) );
+	         }
+                 #endif
+                 break;
+
+            default:
+                 break;
+          }
+          omFreeSize((ADDRESS)r->cf, sizeof(n_Procs_s));
+          r->cf=NULL;
+        }
+        else
+        {
+          WarnS("cf_root list destroyed");
+        }
+      }
+    }
+    if (r->algring!=NULL)
+    {
+      rKill(r->algring);
+      r->algring=NULL;
+    }
+  }
+}
Index: kernel/numbers.h
===================================================================
--- kernel/numbers.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/numbers.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,87 @@
+#ifndef NUMBERS_H
+#define NUMBERS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: numbers.h,v 1.1.1.1 2003-10-06 12:15:58 Singular Exp $ */
+/*
+* ABSTRACT: interface to coefficient aritmetics
+*/
+#include "structs.h"
+
+#define n_Copy(n, r)          (r)->cf->cfCopy(n,r)
+#define n_Delete(n, r)        (r)->cf->cfDelete(n,r)
+#define n_Mult(n1, n2, r)     (r)->cf->nMult(n1, n2)
+#define n_Add(n1, n2, r)      (r)->cf->nAdd(n1, n2)
+#define n_IsZero(n, r)        (r)->cf->nIsZero(n)
+#define n_Equal(n1, n2, r)    (r)->cf->nEqual(n1, n2)
+#define n_Neg(n, r)           (r)->cf->nNeg(n)
+#define n_Sub(n1, n2, r)      (r)->cf->nSub(n1, n2)
+//#define n_GetChar(r)          ((r)->cf->nChar)
+#define n_GetChar(r)          ((r)->ch)
+#define n_Init(i, r)          (r)->cf->nInit(i)
+#define n_IsOne(n, r)         (r)->cf->nIsOne(n)
+#define n_IsMOne(n, r)        (r)->cf->nIsMOne(n)
+#define n_GreaterZero(n, r)   (r)->cf->nGreaterZero(n)
+#define n_Write(n, r)         (r)->cf->nWrite(n)
+#define n_Normalize(n, r)     (r)->cf->nNormalize(n)
+#define n_Gcd(a, b, r)        (r)->cf->nGcd(a,b,r)
+#define n_IntDiv(a, b, r)     (r)->cf->nIntDiv(a,b)
+#define n_InpMult(a, b, r)    (r)->cf->nInpMult(a,b,r)
+
+/* variables */
+extern short fftable[];
+
+/* prototypes */
+extern numberfunc nMult, nSub ,nAdd ,nDiv, nIntDiv, nIntMod, nExactDiv;
+extern void    (*nNew)(number * a);
+extern number  (*nInit)(int i);
+extern number  (*nPar)(int i);
+extern int     (*nParDeg)(number n);
+extern int     (*nSize)(number n);
+extern int     (*nInt)(number &n);
+extern number  (*nNeg)(number a);
+extern number  (*nInvers)(number a);
+extern number  (*nCopy)(number a);
+extern number  (*nRePart)(number a);
+extern number  (*nImPart)(number a);
+extern void    (*nWrite)(number &a);
+extern char *  (*nRead)(char * s, number * a);
+extern void    (*nNormalize)(number &a);
+extern BOOLEAN (*nGreater)(number a,number b),
+               (*nEqual)(number a,number b),
+               (*nIsZero)(number a),
+               (*nIsOne)(number a),
+               (*nIsMOne)(number a),
+               (*nGreaterZero)(number a);
+extern void    (*nPower)(number a, int i, number * result);
+extern number (*nGcd)(number a, number b, const ring r);
+extern number (*nLcm)(number a, number b, const ring r);
+
+extern number nNULL; /* the 0 as constant */
+
+extern void    (*n__Delete)(number * a, const ring r);
+#define nTest(a) (1)
+#define nDelete(A) (currRing)->cf->cfDelete(A,currRing)
+#define nGetDenom(N) (currRing->cf->n_GetDenom((N),currRing))
+
+#define nSetMap(R) (currRing->cf->cfSetMap(R,currRing))
+extern char *  (*nName)(number n);
+
+void nDummy1(number* d);
+void ndDelete(number* d, const ring r);
+void nDummy2(number &d);
+number ndGcd(number a, number b, const ring);
+number ndCopy(number a);
+void   ndInpMult(number &a, number b, const ring r);
+
+#ifdef LDEBUG
+void nDBDummy1(number* d,char *f, int l);
+#endif
+#define nGetChar() n_GetChar(currRing)
+
+void nInitChar(ring r);
+void nKillChar(ring r);
+void nSetChar(ring r);
+
+#endif
Index: kernel/omSingularConfig.h
===================================================================
--- kernel/omSingularConfig.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/omSingularConfig.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,62 @@
+/*******************************************************************
+ *  File:    omSingularConfig.h
+ *  Purpose: declaration of External Config stuff for omalloc
+ *           This file is inlcuded by omDefaultConfig.h, i.e., at the the time
+ *           the omalloc library is built. Any changes to the default config
+ *           of omalloc should be done here (and, of course, you need to
+ *           rebuilt the library).
+ *  Author:  obachman@mathematik.uni-kl.de (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: omSingularConfig.h,v 1.1.1.1 2003-10-06 12:15:58 Singular Exp $
+ *******************************************************************/
+#ifndef OM_SINGULAR_CONFIG_H
+#define OM_SINGULAR_CONFIG_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define OM_MALLOC_HOOK(size)                OM_SINGULAR_HOOK
+#define OM_FREE_HOOK(size)                  OM_SINGULAR_HOOK
+#define OM_ALLOC_BINPAGE_HOOK               OM_SINGULAR_HOOK
+#define OM_FREE_BINPAGE_HOOK                OM_SINGULAR_HOOK
+
+#ifdef OM_ALLOC_SYSTEM_C
+int om_sing_opt_show_mem = 0;
+size_t om_sing_last_reported_size = 0;
+#else
+extern int om_sing_opt_show_mem;
+extern size_t om_sing_last_reported_size;
+#endif
+
+/* number of bytes for difference to report: every 1 MByte */
+#define SING_REPORT_THRESHOLD 1000*1024
+#define OM_SINGULAR_HOOK                                                        \
+do                                                                              \
+{                                                                               \
+  if (om_sing_opt_show_mem)                                                     \
+  {                                                                             \
+    size_t _current_bytes = om_Info.CurrentBytesFromMalloc +                    \
+                            (om_Info.UsedPages << LOG_BIT_SIZEOF_SYSTEM_PAGE);  \
+    size_t _diff = (_current_bytes > om_sing_last_reported_size ?               \
+                   _current_bytes - om_sing_last_reported_size :                \
+                   om_sing_last_reported_size - _current_bytes);                \
+    if (_diff >= SING_REPORT_THRESHOLD)                                         \
+    {                                                                           \
+      fprintf(stdout, "[%ldk]", (_current_bytes + 1023)/1024);                   \
+      fflush(stdout);                                                           \
+      om_sing_last_reported_size = _current_bytes;                              \
+    }                                                                           \
+  }                                                                             \
+}                                                                               \
+while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OM_SINGULAR_CONFIG_H */
Index: kernel/pDebug.cc
===================================================================
--- kernel/pDebug.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/pDebug.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,363 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pDebug.h
+ *  Purpose: implementation of debug related poly routines
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: pDebug.cc,v 1.1.1.1 2003-10-06 12:15:57 Singular Exp $
+ *******************************************************************/
+
+#ifndef PDEBUG_CC
+#define PDEBUG_CC
+#include <stdarg.h>
+#include <stdio.h>
+
+
+#include "mod2.h"
+#ifdef PDEBUG
+
+// do the following to always enforce checking of pSetm
+// #undef PDEBUG
+// #define PDEBUG 2
+
+#include "p_polys.h"
+#include "febase.h"
+#include "omalloc.h"
+#include "ring.h"
+#include "numbers.h"
+
+/***************************************************************
+ *
+ * Error reporting
+ *
+ ***************************************************************/
+// avoid recursive calls
+static BOOLEAN d_poly_error_reporting = FALSE;
+BOOLEAN dPolyReportError(poly p, ring r, const char* fmt, ...)
+{
+  if (d_poly_error_reporting) return FALSE;
+  d_poly_error_reporting = TRUE;
+  va_list ap;
+  va_start(ap, fmt);
+
+  fprintf(stderr, "\n// ***dPolyError: ");
+  vfprintf(stderr, fmt, ap);
+  fprintf(stderr, "\n occured at\n");
+  omPrintCurrentBackTraceMax(stderr, 8);
+  if (p != NULL)
+  {
+    if (r == currRing)
+    {
+      fprintf(stderr, " occured for poly: ");
+      p_wrp(p, r);
+      omPrintAddrInfo(stderr, p, " ");
+    }
+    else
+    {
+      omPrintAddrInfo(stderr, p, " occured for poly: ");
+    }
+  }
+  dErrorBreak();
+  d_poly_error_reporting = FALSE;
+  return FALSE;
+}
+
+/***************************************************************
+ *
+ * checking for ring stuff
+ *
+ ***************************************************************/
+BOOLEAN p_LmCheckIsFromRing(poly p, ring r)
+{
+  if (p != NULL)
+  {
+    void* custom = omGetCustomOfAddr(p);
+    if (custom != NULL)
+    {
+      pPolyAssumeReturnMsg(custom == r ||
+                           // be more sloppy for qrings
+                           (r->qideal != NULL &&
+                            omIsBinPageAddr(p) &&
+                            omSizeWOfAddr(p)==r->PolyBin->sizeW) ||
+                           rEqual((ring) custom, r, FALSE),
+                           "monomial not from specified ring");
+      return TRUE;
+    }
+    else
+    {
+      pPolyAssumeReturn(omIsBinPageAddr(p) && omSizeWOfAddr(p)==r->PolyBin->sizeW);
+      return TRUE;
+    }
+    return FALSE;
+  }
+  return TRUE;
+}
+
+BOOLEAN p_CheckIsFromRing(poly p, ring r)
+{
+  while (p!=NULL)
+  {
+    pFalseReturn(p_LmCheckIsFromRing(p, r));
+    pIter(p);
+  }
+  return TRUE;
+}
+
+BOOLEAN p_CheckPolyRing(poly p, ring r)
+{
+  pAssumeReturn(r != NULL && r->PolyBin != NULL);
+  return p_CheckIsFromRing(p, r);
+}
+
+BOOLEAN p_LmCheckPolyRing(poly p, ring r)
+{
+  pAssumeReturn(r != NULL && r->PolyBin != NULL);
+  pAssumeReturn(p != NULL);
+  return p_LmCheckIsFromRing(p, r);
+}
+BOOLEAN p_CheckRing(ring r)
+{
+  pAssumeReturn(r != NULL && r->PolyBin != NULL);
+  return TRUE;
+}
+
+/***************************************************************
+ *
+ * Debugging/statistics of pDivisibleBy
+ *
+ ***************************************************************/
+BOOLEAN p_DebugLmDivisibleByNoComp(poly a, poly b, ring r)
+{
+  int i=r->N;
+
+  do
+  {
+    if (p_GetExp(a,i,r) > p_GetExp(b,i,r))
+      return FALSE;
+    i--;
+  }
+  while (i);
+  return TRUE;
+}
+
+
+/***************************************************************
+ *
+ * Misc things helpful for debugging
+ *
+ ***************************************************************/
+BOOLEAN pIsMonomOf(poly p, poly m)
+{
+  if (m == NULL) return TRUE;
+  while (p != NULL)
+  {
+    if (p == m) return TRUE;
+    pIter(p);
+  }
+  return FALSE;
+}
+BOOLEAN pHaveCommonMonoms(poly p, poly q)
+{
+  while (p != NULL)
+  {
+    if (pIsMonomOf(q, p))
+    {
+      return TRUE;
+    }
+    pIter(p);
+  }
+  return FALSE;
+}
+
+/***************************************************************
+ *
+ * Testing of polys
+ *
+ ***************************************************************/
+extern void p_Setm_General(poly p, ring r);
+
+static poly p_DebugInit(poly p, ring src_ring, ring dest_ring)
+{
+  poly d_p = p_Init(dest_ring);
+  int i;
+  assume(dest_ring->N == src_ring->N);
+
+  for (i=1; i<= src_ring->N; i++)
+  {
+    p_SetExp(d_p, i, p_GetExp(p, i, src_ring), dest_ring);
+  }
+  if (rRing_has_Comp(dest_ring))
+    p_SetComp(d_p, p_GetComp(p, src_ring), dest_ring);
+
+  p_Setm_General(d_p, dest_ring);
+  return d_p;
+}
+
+BOOLEAN _p_Test(poly p, ring r, int level)
+{
+  assume(r->cf !=NULL);
+
+  if (PDEBUG > level) level = PDEBUG;
+  if (level < 0 || p == NULL) return TRUE;
+
+  poly p_prev = NULL;
+
+  // check addr with level+1 so as to check bin/page of addr
+  pPolyAssumeReturnMsg(omTestBinAddrSize(p, (r->PolyBin->sizeW)*SIZEOF_LONG, level+1)
+                        == omError_NoError, "memory error");
+
+  pFalseReturn(p_CheckRing(r));
+
+  // this checks that p does not contain a loop: rather expensive O(length^2)
+  if (level > 1)
+    pFalseReturn(omTestList(p, level) == omError_NoError);
+
+  int ismod = p_GetComp(p, r) > 0;
+
+  while (p != NULL)
+  {
+    // ring check
+    pFalseReturn(p_LmCheckIsFromRing(p, r));
+    // omAddr check
+    pPolyAssumeReturnMsg(omTestBinAddrSize(p, (r->PolyBin->sizeW)*SIZEOF_LONG, 1)
+                     == omError_NoError, "memory error");
+    // number/coef check
+    pPolyAssumeReturnMsg(p->coef != NULL || (n_GetChar(r) >= 2), "NULL coef");
+    pPolyAssumeReturnMsg(!n_IsZero(p->coef, r), "Zero coef");
+
+    // check for valid comp
+    pPolyAssumeReturnMsg(p_GetComp(p, r) >= 0 && (p_GetComp(p, r)<65000), "component out of range ?");
+    // check for mix poly/vec representation
+    pPolyAssumeReturnMsg(ismod == (p_GetComp(p, r) > 0), "mixed poly/vector");
+
+    // special check for ringorder_s/S
+    if (r->order[1] == ringorder_S)
+    {
+      long c1, cc1, ccc1, ec1;
+      sro_ord* o = &(r->typ[1]);
+
+      c1 = p_GetComp(p, r);
+      cc1 = o->data.syzcomp.Components[c1];
+      ccc1 = o->data.syzcomp.ShiftedComponents[cc1];
+      pPolyAssumeReturnMsg(c1 == 0 || cc1 != 0, "Component <-> TrueComponent zero mismatch");
+      pPolyAssumeReturnMsg(c1 == 0 || ccc1 != 0,"Component <-> ShiftedComponent zero mismatch");
+      ec1 = p->exp[r->typ[1].data.syzcomp.place];
+      pPolyAssumeReturnMsg(ec1 == ccc1, "Shifted comp out of sync. should %d, is %d");
+    }
+
+    // check that p_Setm works ok
+    if (level > 0)
+    {
+      poly p_should_equal = p_DebugInit(p, r, r);
+      pPolyAssumeReturnMsg(p_ExpVectorEqual(p, p_should_equal, r), "p_Setm field(s) out of sync");
+      p_LmFree(p_should_equal, r);
+    }
+
+    // check order
+    if (p_prev != NULL)
+    {
+      int cmp = p_LmCmp(p_prev, p, r);
+      if (cmp == 0)
+      {
+        _pPolyAssumeReturnMsg(0, "monoms p and p->next are equal", p_prev, r);
+      }
+      else
+        _pPolyAssumeReturnMsg(p_LmCmp(p_prev, p, r) == 1, "wrong order", p_prev, r);
+
+      // check that compare worked sensibly
+      if (level > 1 && p_GetComp(p_prev, r) == p_GetComp(p, r))
+      {
+        int i;
+        for (i=r->N; i>0; i--)
+        {
+          if (p_GetExp(p_prev, i, r) != p_GetExp(p, i, r)) break;
+        }
+        _pPolyAssumeReturnMsg(i > 0, "Exponents equal but compare different", p_prev, r);
+      }
+    }
+    p_prev = p;
+    pIter(p);
+  }
+  return TRUE;
+}
+
+BOOLEAN _p_LmTest(poly p, ring r, int level)
+{
+  if (level < 0 || p == NULL) return TRUE;
+  poly pnext = pNext(p);
+  pNext(p) = NULL;
+  BOOLEAN test_res = _p_Test(p, r, level);
+  pNext(p) = pnext;
+  return test_res;
+}
+
+BOOLEAN _pp_Test(poly p, ring lmRing, ring tailRing, int level)
+{
+  if (PDEBUG > level) level = PDEBUG;
+  if (level < 0 || p == NULL) return TRUE;
+  if (pNext(p) == NULL || lmRing == tailRing) return _p_Test(p, lmRing, level);
+
+  pFalseReturn(_p_LmTest(p, lmRing, level));
+  pFalseReturn(_p_Test(pNext(p), tailRing, level));
+
+  // check that lm > Lm(tail)
+  if (level > 1)
+  {
+    poly lm = p;
+    poly tail = p_DebugInit(pNext(p), tailRing, lmRing);
+    poly pnext = pNext(lm);
+    pNext(lm) = tail;
+    BOOLEAN cmp = p_LmCmp(lm, tail, lmRing);
+    if (cmp != 1)
+      dPolyReportError(lm, lmRing, "wrong order: lm <= Lm(tail)");
+    p_LmFree(tail, lmRing);
+    pNext(lm) = pnext;
+    return (cmp == 1);
+  }
+  return TRUE;
+}
+
+#endif // PDEBUG
+
+#include "pInline1.h"
+
+#if defined(PDEBUG) || defined(PDIV_DEBUG)
+static unsigned long pDivisibleBy_number = 1;
+static unsigned long pDivisibleBy_FALSE = 1;
+static unsigned long pDivisibleBy_ShortFalse = 1;
+BOOLEAN pDebugLmShortDivisibleBy(poly p1, unsigned long sev_1, ring r_1,
+                               poly p2, unsigned long not_sev_2, ring r_2)
+{
+  _pPolyAssume(p_GetShortExpVector(p1, r_1) == sev_1, p1, r_1);
+  _pPolyAssume(p_GetShortExpVector(p2, r_2) == ~ not_sev_2, p2, r_2);
+
+  pDivisibleBy_number++;
+  BOOLEAN ret;
+  if (r_1 == r_2)
+    ret = p_LmDivisibleBy(p1, p2, r_1);
+  else
+    ret = p_LmDivisibleBy(p1, r_1, p2, r_2);
+
+  if (! ret) pDivisibleBy_FALSE++;
+  if (sev_1 & not_sev_2)
+  {
+    pDivisibleBy_ShortFalse++;
+    if (ret)
+      dReportError("p1 divides p2, but sev's are wrong");
+  }
+  return ret;
+}
+
+void pPrintDivisbleByStat()
+{
+  Print("#Tests: %d; #FALSE %d(%d); #SHORT %d(%d)\n",
+        pDivisibleBy_number,
+        pDivisibleBy_FALSE, (unsigned long) ((double)pDivisibleBy_FALSE*((double) 100)/(double)pDivisibleBy_number),
+        pDivisibleBy_ShortFalse, (unsigned long) ((double)pDivisibleBy_ShortFalse*((double)100)/(double)pDivisibleBy_FALSE));
+}
+
+#endif // PDEBUG
+
+#endif // PDEBUG_CC
Index: kernel/pInline0.cc
===================================================================
--- kernel/pInline0.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/pInline0.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,22 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pInline.cc
+ *  Purpose: implementation of poly level 0 functions
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: pInline0.cc,v 1.1.1.1 2003-10-06 12:15:58 Singular Exp $
+ *******************************************************************/
+#ifndef PINLINE0_CC
+
+#include "mod2.h"
+
+#define PINLINE0_CC
+#undef DO_PINLINE0
+
+
+#include "pInline0.h"
+
+#endif // PINLINE_CC
+
Index: kernel/pInline0.h
===================================================================
--- kernel/pInline0.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/pInline0.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,184 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pInline.cc
+ *  Purpose: implementation of poly Level 0 functions
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: pInline0.h,v 1.1.1.1 2003-10-06 12:15:58 Singular Exp $
+ *******************************************************************/
+#ifndef PINLINE0_H
+#define PINLINE0_H
+
+#if defined(DO_PINLINE0)
+#define PINLINE0 static inline
+#else
+#define PINLINE0
+#endif
+
+#include "p_polys.h"
+#include "ring.h"
+
+PINLINE0 int p_SetCompP(poly p, int i, ring r)
+{
+  if (p == NULL) return 0;
+
+#ifdef PDEBUG
+  poly q = p;
+#endif
+
+  int l = 0;
+
+  if (rOrd_SetCompRequiresSetm(r))
+  {
+    do
+    {
+      p_SetComp(p, i, r);
+      p_SetmComp(p, r);
+      l++;
+      pIter(p);
+    }
+    while (p != NULL);
+  }
+  else
+  {
+    do
+    {
+      p_SetComp(p, i, r);
+      l++;
+      pIter(p);
+    }
+    while(p != NULL);
+  }
+#ifdef PDEBUG
+  p_Test(q, r);
+  assume(l == pLength(q));
+#endif
+  return l;
+}
+
+PINLINE0 int p_SetCompP(poly p, int i, ring lmRing, ring tailRing)
+{
+  if (p != NULL)
+  {
+    p_SetComp(p, i, lmRing);
+    p_SetmComp(p, lmRing);
+    return p_SetCompP(pNext(p), i, tailRing) + 1;
+  }
+  else
+    return 0;
+}
+
+// returns minimal column number in the modul element a (or 0)
+PINLINE0 long p_MinComp(poly p, ring lmRing, ring tailRing)
+{
+  long result,i;
+
+  if(p==NULL) return 0;
+  result = p_GetComp(p,lmRing);
+  if (result != 0)
+  {
+    loop
+    {
+      pIter(p);
+      if(p==NULL) break;
+      i = p_GetComp(p,tailRing);
+      if (i<result) result = i;
+    }
+  }
+  return result;
+}
+
+// returns maximal column number in the modul element a (or 0)
+PINLINE0 long p_MaxComp(poly p, ring lmRing, ring tailRing)
+{
+  long result,i;
+
+  if(p==NULL) return 0;
+  result = p_GetComp(p, lmRing);
+  if (result != 0)
+  {
+    loop
+    {
+      pIter(p);
+      if(p==NULL) break;
+      i = p_GetComp(p, tailRing);
+      if (i>result) result = i;
+    }
+  }
+  return result;
+}
+
+BOOLEAN   p_IsConstantPoly(const poly p, const ring r)
+{
+  poly pp=p;
+  while(pp!=NULL)
+  {
+    if (! p_LmIsConstantComp(pp, r))
+      return FALSE;
+    pIter(pp);
+  }
+  return TRUE;
+}
+
+/***************************************************************
+ *
+ * poly things which are independent of ring
+ *
+ ***************************************************************/
+PINLINE0 poly pReverse(poly p)
+{
+  if (p == NULL || pNext(p) == NULL) return p;
+
+  poly q = pNext(p), // == pNext(p)
+    qn;
+  pNext(p) = NULL;
+  do
+  {
+    qn = pNext(q);
+    pNext(q) = p;
+    p = q;
+    q = qn;
+  }
+  while (qn != NULL);
+  return p;
+}
+
+
+/*2
+* returns the length of a (numbers of monomials)
+*/
+PINLINE0 int pLength(poly a)
+{
+  int l = 0;
+
+  while (a!=NULL)
+  {
+    pIter(a);
+    l++;
+  }
+  return l;
+}
+
+/*2
+* returns the length of a (numbers of monomials)
+*/
+PINLINE0 poly pLast(poly a, int &l)
+{
+  if (a == NULL)
+  {
+    l = 0;
+    return NULL;
+  }
+  l = 1;
+  while (pNext(a)!=NULL)
+  {
+    pIter(a);
+    l++;
+  }
+  return a;
+}
+
+#endif // PINLINE_CC
+
Index: kernel/pInline1.cc
===================================================================
--- kernel/pInline1.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/pInline1.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,31 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pInline1.cc
+ *  Purpose: implementation of poly procs which iter over ExpVector
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: pInline1.cc,v 1.1.1.1 2003-10-06 12:15:58 Singular Exp $
+ *******************************************************************/
+#ifndef PINLINE1_CC
+#define PINLINE1_CC
+
+#include "mod2.h"
+
+#ifdef PDEBUG
+
+#if PDEBUG < 1
+#undef PDEBUG
+#define PDEBUG 1
+#endif
+
+#undef NO_INLINE1
+#define NO_INLINE1
+
+#endif // PDEBUG
+
+#include "p_polys.h"
+
+#endif // PINLINE1_CC
+
Index: kernel/pInline1.h
===================================================================
--- kernel/pInline1.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/pInline1.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,543 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pInline1.h
+ *  Purpose: implementation of poly procs which iter over ExpVector
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: pInline1.h,v 1.1.1.1 2003-10-06 12:15:52 Singular Exp $
+ *******************************************************************/
+#ifndef PINLINE1_H
+#define PINLINE1_H
+
+#ifndef PDIV_DEBUG
+// define to enable debugging/statistics of pLmShortDivisibleBy
+// #define PDIV_DEBUG
+#endif
+#include <mylimits.h>
+#include "p_MemCmp.h"
+#include "structs.h"
+#include "numbers.h"
+
+#if PDEBUG > 0 || defined(NO_PINLINE1)
+
+#define _p_LmCmpAction(p, q, r, actionE, actionG, actionS)  \
+do                                                          \
+{                                                           \
+  int _cmp = p_LmCmp(p,q,r);                                \
+  if (_cmp == 0) actionE;                                   \
+  if (_cmp == 1) actionG;                                   \
+  actionS;                                                  \
+}                                                           \
+while(0)
+
+#else
+
+#define _p_LmCmpAction(p, q, r, actionE, actionG, actionS)                      \
+ p_MemCmp_LengthGeneral_OrdGeneral(p->exp, q->exp, r->CmpL_Size, r->ordsgn,    \
+                                   actionE, actionG, actionS)
+
+#endif
+
+#ifdef PDIV_DEBUG
+BOOLEAN pDebugLmShortDivisibleBy(poly p1, unsigned long sev_1, ring r_1,
+                                 poly p2, unsigned long not_sev_2, ring r_2);
+BOOLEAN p_DebugLmDivisibleByNoComp(poly a, poly b, ring r);
+#define pDivAssume  pAssume
+#else
+#define pDivAssume(x)   ((void)0)
+#endif
+
+#if !defined(NO_PINLINE1) || defined(PINLINE1_CC)
+
+#include "omalloc.h"
+#include "numbers.h"
+#include "p_polys.h"
+#include "p_MemAdd.h"
+#include "p_MemCopy.h"
+
+/***************************************************************
+ *
+ * Allocation/Initalization/Deletion
+ *
+ ***************************************************************/
+// adjustments for negative weights
+PINLINE1 void p_MemAdd_NegWeightAdjust(poly p, ring r)
+{
+  if (r->NegWeightL_Offset != NULL)
+  {
+    for (int i=r->NegWeightL_Size-1; i>=0; i--)
+    {
+      p->exp[r->NegWeightL_Offset[i]] -= POLY_NEGWEIGHT_OFFSET;
+    }
+  }
+}
+PINLINE1 void p_MemSub_NegWeightAdjust(poly p, ring r)
+{
+  if (r->NegWeightL_Offset != NULL)
+  {
+    for (int i=r->NegWeightL_Size-1; i>=0; i--)
+    {
+      p->exp[r->NegWeightL_Offset[i]] += POLY_NEGWEIGHT_OFFSET;
+    }
+  }
+}
+// ExpVextor(d_p) = ExpVector(s_p)
+PINLINE1 void p_ExpVectorCopy(poly d_p, poly s_p, ring r)
+{
+  p_LmCheckPolyRing1(d_p, r);
+  p_LmCheckPolyRing1(s_p, r);
+  p_MemCopy_LengthGeneral(d_p->exp, s_p->exp, r->ExpL_Size);
+}
+
+PINLINE1 poly p_Init(ring r, omBin bin)
+{
+  p_CheckRing1(r);
+  pAssume1(bin != NULL && r->PolyBin->sizeW == bin->sizeW);
+  poly p;
+  omTypeAlloc0Bin(poly, p, bin);
+  p_MemAdd_NegWeightAdjust(p, r);
+  p_SetRingOfLm(p, r);
+  return p;
+}
+PINLINE1 poly p_Init(ring r)
+{
+  return p_Init(r, r->PolyBin);
+}
+
+PINLINE1 poly p_LmInit(poly p, ring r)
+{
+  p_LmCheckPolyRing1(p, r);
+  poly np;
+  omTypeAllocBin(poly, np, r->PolyBin);
+  p_SetRingOfLm(np, r);
+  p_ExpVectorCopy(np, p, r);
+  _pNext(np) = NULL;
+  _pSetCoeff0(np, NULL);
+  return np;
+}
+PINLINE1 poly p_LmInit(poly s_p, ring s_r, ring d_r)
+{
+  pAssume1(d_r != NULL);
+  return p_LmInit(s_p, s_r, d_r, d_r->PolyBin);
+}
+PINLINE1 poly p_LmInit(poly s_p, ring s_r, ring d_r, omBin d_bin)
+{
+  p_LmCheckPolyRing1(s_p, s_r);
+  p_CheckRing(d_r);
+  pAssume1(d_r->N <= s_r->N);
+  poly d_p = p_Init(d_r, d_bin);
+  for (int i=d_r->N; i>0; i--)
+  {
+    p_SetExp(d_p, i, p_GetExp(s_p, i,s_r), d_r);
+  }
+  if (rRing_has_Comp(d_r))
+  {
+    p_SetComp(d_p, p_GetComp(s_p,s_r), d_r);
+  }
+  p_Setm(d_p, d_r);
+  return d_p;
+}
+PINLINE1 poly p_Head(poly p, ring r)
+{
+  if (p == NULL) return NULL;
+  p_LmCheckPolyRing1(p, r);
+  poly np;
+  omTypeAllocBin(poly, np, r->PolyBin);
+  p_SetRingOfLm(np, r);
+  p_ExpVectorCopy(np, p, r);
+  _pNext(np) = NULL;
+  _pSetCoeff0(np, n_Copy(_pGetCoeff(p), r));
+  return np;
+}
+
+PINLINE1 poly p_LmShallowCopyDelete(poly p, const ring r, omBin bin)
+{
+  p_LmCheckPolyRing1(p, r);
+  pAssume1(bin->sizeW == r->PolyBin->sizeW);
+  poly new_p = p_New(r);
+  p_MemCopy_LengthGeneral(new_p->exp, p->exp, r->ExpL_Size);
+  pSetCoeff0(new_p, pGetCoeff(p));
+  pNext(new_p) = pNext(p);
+  omFreeBinAddr(p);
+  return new_p;
+}
+
+/***************************************************************
+ *
+ * Operation on ExpVectors
+ *
+ ***************************************************************/
+// ExpVector(p1) += ExpVector(p2)
+PINLINE1 void p_ExpVectorAdd(poly p1, poly p2, ring r)
+{
+  p_LmCheckPolyRing1(p1, r);
+  p_LmCheckPolyRing1(p2, r);
+#if PDEBUG >= 1
+  for (int i=1; i<=r->N; i++)
+    pAssume1((unsigned long) (p_GetExp(p1, i, r) + p_GetExp(p2, i, r)) <= r->bitmask);
+  pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0);
+#endif
+
+  p_MemAdd_LengthGeneral(p1->exp, p2->exp, r->ExpL_Size);
+  p_MemAdd_NegWeightAdjust(p1, r);
+}
+// ExpVector(p1) -= ExpVector(p2)
+PINLINE1 void p_ExpVectorSub(poly p1, poly p2, ring r)
+{
+  p_LmCheckPolyRing1(p1, r);
+  p_LmCheckPolyRing1(p2, r);
+#if PDEBUG >= 1
+  for (int i=1; i<=r->N; i++)
+    pAssume1(p_GetExp(p1, i, r) >= p_GetExp(p2, i, r));
+  pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0 ||
+          p_GetComp(p1, r) == p_GetComp(p2, r));
+#endif
+
+  p_MemSub_LengthGeneral(p1->exp, p2->exp, r->ExpL_Size);
+  p_MemSub_NegWeightAdjust(p1, r);
+
+}
+// ExpVector(p1) += ExpVector(p2) - ExpVector(p3)
+PINLINE1 void p_ExpVectorAddSub(poly p1, poly p2, poly p3, ring r)
+{
+  p_LmCheckPolyRing1(p1, r);
+  p_LmCheckPolyRing1(p2, r);
+  p_LmCheckPolyRing1(p3, r);
+#if PDEBUG >= 1
+  for (int i=1; i<=r->N; i++)
+    pAssume1(p_GetExp(p1, i, r) + p_GetExp(p2, i, r) >= p_GetExp(p3, i, r));
+  pAssume1(p_GetComp(p1, r) == 0 ||
+           (p_GetComp(p2, r) - p_GetComp(p3, r) == 0) ||
+           (p_GetComp(p1, r) == p_GetComp(p2, r) - p_GetComp(p3, r)));
+#endif
+
+  p_MemAddSub_LengthGeneral(p1->exp, p2->exp, p3->exp, r->ExpL_Size);
+  // no need to adjust in case of NegWeights
+}
+
+// ExpVector(pr) = ExpVector(p1) + ExpVector(p2)
+PINLINE1 void p_ExpVectorSum(poly pr, poly p1, poly p2, ring r)
+{
+  p_LmCheckPolyRing1(p1, r);
+  p_LmCheckPolyRing1(p2, r);
+  p_LmCheckPolyRing1(pr, r);
+#if PDEBUG >= 1
+  for (int i=1; i<=r->N; i++)
+    pAssume1((unsigned long) (p_GetExp(p1, i, r) + p_GetExp(p2, i, r)) <= r->bitmask);
+  pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0);
+#endif
+
+  p_MemSum_LengthGeneral(pr->exp, p1->exp, p2->exp, r->ExpL_Size);
+  p_MemAdd_NegWeightAdjust(p1, r);
+}
+// ExpVector(pr) = ExpVector(p1) - ExpVector(p2)
+PINLINE1 void p_ExpVectorDiff(poly pr, poly p1, poly p2, ring r)
+{
+  p_LmCheckPolyRing1(p1, r);
+  p_LmCheckPolyRing1(p2, r);
+  p_LmCheckPolyRing1(pr, r);
+#if PDEBUG >= 2
+  for (int i=1; i<=r->N; i++)
+    pAssume1(p_GetExp(p1, i, r) >= p_GetExp(p2, i, r));
+  pAssume1(!rRing_has_Comp(r) || p_GetComp(p1, r) == p_GetComp(p2, r));
+#endif
+
+  p_MemDiff_LengthGeneral(pr->exp, p1->exp, p2->exp, r->ExpL_Size);
+  p_MemSub_NegWeightAdjust(p1, r);
+}
+
+PINLINE1 BOOLEAN p_ExpVectorEqual(poly p1, poly p2, ring r)
+{
+  p_LmCheckPolyRing1(p1, r);
+  p_LmCheckPolyRing1(p2, r);
+
+  int i = r->ExpL_Size;
+  unsigned long *ep = p1->exp;
+  unsigned long *eq = p2->exp;
+
+  do
+  {
+    i--;
+    if (ep[i] != eq[i]) return FALSE;
+  }
+  while (i);
+  return TRUE;
+}
+
+PINLINE1 unsigned long p_ExpVectorQuerSum(poly p, ring r)
+{
+  p_LmCheckPolyRing1(p, r);
+  unsigned long s = p_GetTotalDegree(p->exp[r->VarL_Offset[0]],
+                                     r,
+                                     r->MinExpPerLong);
+  for (int i=r->VarL_Size-1; i>0; i--)
+  {
+    s += p_GetTotalDegree(p->exp[r->VarL_Offset[i]], r);
+  }
+  return s;
+}
+
+PINLINE1 void p_GetExpV(poly p, int *ev, ring r)
+{
+  p_LmCheckPolyRing1(p, r);
+  for (int j = r->N; j; j--)
+      ev[j] = p_GetExp(p, j, r);
+
+  ev[0] = _p_GetComp(p, r);
+}
+PINLINE1 void p_SetExpV(poly p, int *ev, ring r)
+{
+  p_LmCheckPolyRing1(p, r);
+  for (int j = r->N; j; j--)
+      p_SetExp(p, j, ev[j], r);
+
+  p_SetComp(p, ev[0],r);
+  p_Setm(p, r);
+}
+
+/***************************************************************
+ *
+ * Comparison w.r.t. monomial ordering
+ *
+ ***************************************************************/
+PINLINE1 int p_LmCmp(poly p, poly q, ring r)
+{
+  p_LmCheckPolyRing1(p, r);
+  p_LmCheckPolyRing1(q, r);
+
+  p_MemCmp_LengthGeneral_OrdGeneral(p->exp, q->exp, r->CmpL_Size, r->ordsgn,
+                                    return 0, return 1, return -1);
+}
+
+
+/***************************************************************
+ *
+ * divisibility
+ *
+ ***************************************************************/
+// return: FALSE, if there exists i, such that a->exp[i] > b->exp[i]
+//         TRUE, otherwise
+// (1) Consider long vars, instead of single exponents
+// (2) Clearly, if la > lb, then FALSE
+// (3) Suppose la <= lb, and consider first bits of single exponents in l:
+//     if TRUE, then value of these bits is la ^ lb
+//     if FALSE, then la-lb causes an "overflow" into one of those bits, i.e.,
+//               la ^ lb != la - lb
+static inline BOOLEAN _p_LmDivisibleByNoComp(poly a, poly b, ring r)
+{
+  int i=r->VarL_Size - 1;
+  unsigned long divmask = r->divmask;
+  unsigned long la, lb;
+
+  if (r->VarL_LowIndex >= 0)
+  {
+    i += r->VarL_LowIndex;
+    do
+    {
+      la = a->exp[i];
+      lb = b->exp[i];
+      if ((la > lb) ||
+          (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask)))
+      {
+        pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE);
+        return FALSE;
+      }
+      i--;
+    }
+    while (i>=r->VarL_LowIndex);
+  }
+  else
+  {
+    do
+    {
+      la = a->exp[r->VarL_Offset[i]];
+      lb = b->exp[r->VarL_Offset[i]];
+      if ((la > lb) ||
+          (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask)))
+      {
+        pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE);
+        return FALSE;
+      }
+      i--;
+    }
+    while (i>=0);
+  }
+  pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == TRUE);
+  return TRUE;
+}
+
+static inline BOOLEAN _p_LmDivisibleByNoComp(poly a, ring r_a, poly b, ring r_b)
+{
+  int i=r_a->N;
+  pAssume1(r_a->N == r_b->N);
+
+  do
+  {
+    if (p_GetExp(a,i,r_a) > p_GetExp(b,i,r_b))
+      return FALSE;
+    i--;
+  }
+  while (i);
+  return TRUE;
+}
+static inline BOOLEAN _p_LmDivisibleBy(poly a, poly b, ring r)
+{
+  if (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r))
+    return _p_LmDivisibleByNoComp(a, b, r);
+  return FALSE;
+}
+static inline BOOLEAN _p_LmDivisibleBy(poly a, ring r_a, poly b, ring r_b)
+{
+  if (p_GetComp(a, r_a) == 0 || p_GetComp(a,r_a) == p_GetComp(b,r_b))
+    return _p_LmDivisibleByNoComp(a, r_a, b, r_b);
+  return FALSE;
+}
+PINLINE1 BOOLEAN p_LmDivisibleByNoComp(poly a, poly b, ring r)
+{
+  p_LmCheckPolyRing1(a, r);
+  p_LmCheckPolyRing1(b, r);
+  return _p_LmDivisibleByNoComp(a, b, r);
+}
+PINLINE1 BOOLEAN p_LmDivisibleBy(poly a, poly b, ring r)
+{
+  p_LmCheckPolyRing1(b, r);
+  pIfThen1(a != NULL, p_LmCheckPolyRing1(b, r));
+  if (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r))
+    return _p_LmDivisibleByNoComp(a, b, r);
+  return FALSE;
+}
+PINLINE1 BOOLEAN p_DivisibleBy(poly a, poly b, ring r)
+{
+  pIfThen1(b!=NULL, p_LmCheckPolyRing1(b, r));
+  pIfThen1(a!=NULL, p_LmCheckPolyRing1(a, r));
+
+  if (a != NULL && (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r)))
+    return _p_LmDivisibleByNoComp(a,b,r);
+  return FALSE;
+}
+PINLINE1 BOOLEAN p_DivisibleBy(poly a, ring r_a, poly b, ring r_b)
+{
+  pIfThen1(b!=NULL, p_LmCheckPolyRing1(b, r_b));
+  pIfThen1(a!=NULL, p_LmCheckPolyRing1(a, r_a));
+  if (a != NULL) return _p_LmDivisibleBy(a, r_a, b, r_b);
+  return FALSE;
+}
+PINLINE1 BOOLEAN p_LmDivisibleBy(poly a, ring r_a, poly b, ring r_b)
+{
+  p_LmCheckPolyRing(a, r_a);
+  p_LmCheckPolyRing(b, r_b);
+  return _p_LmDivisibleBy(a, r_a, b, r_b);
+}
+PINLINE1 BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a,
+                                    poly b, unsigned long not_sev_b, ring r)
+{
+  p_LmCheckPolyRing1(a, r);
+  p_LmCheckPolyRing1(b, r);
+#ifndef PDIV_DEBUG
+  _pPolyAssume2(p_GetShortExpVector(a, r) == sev_a, a, r);
+  _pPolyAssume2(p_GetShortExpVector(b, r) == ~ not_sev_b, b, r);
+
+  if (sev_a & not_sev_b)
+  {
+    pAssume1(p_LmDivisibleByNoComp(a, b, r) == FALSE);
+    return FALSE;
+  }
+  return p_LmDivisibleBy(a, b, r);
+#else
+  return pDebugLmShortDivisibleBy(a, sev_a, r, b, not_sev_b, r);
+#endif
+}
+
+PINLINE1 BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a, ring r_a,
+                                      poly b, unsigned long not_sev_b, ring r_b)
+{
+  p_LmCheckPolyRing1(a, r_a);
+  p_LmCheckPolyRing1(b, r_b);
+#ifndef PDIV_DEBUG
+  _pPolyAssume2(p_GetShortExpVector(a, r_a) == sev_a, a, r_a);
+  _pPolyAssume2(p_GetShortExpVector(b, r_b) == ~ not_sev_b, b, r_b);
+
+  if (sev_a & not_sev_b)
+  {
+    pAssume1(_p_LmDivisibleByNoComp(a, r_a, b, r_b) == FALSE);
+    return FALSE;
+  }
+  return _p_LmDivisibleBy(a, r_a, b, r_b);
+#else
+  return pDebugLmShortDivisibleBy(a, sev_a, r_a, b, not_sev_b, r_b);
+#endif
+}
+
+/***************************************************************
+ *
+ * Misc things on Lm
+ *
+ ***************************************************************/
+// test if the monomial is a constant as a vector component
+// i.e., test if all exponents are zero
+PINLINE1 BOOLEAN p_LmIsConstantComp(const poly p, const ring r)
+{
+  //p_LmCheckPolyRing(p, r);
+  int i = r->VarL_Size - 1;
+
+  do
+  {
+    if (p->exp[r->VarL_Offset[i]] != 0)
+      return FALSE;
+    i--;
+  }
+  while (i >= 0);
+  return TRUE;
+}
+// test if monomial is a constant, i.e. if all exponents and the component
+// is zero
+PINLINE1 BOOLEAN p_LmIsConstant(const poly p, const ring r)
+{
+  if (p_LmIsConstantComp(p, r))
+    return (p_GetComp(p, r) == 0);
+  return FALSE;
+}
+
+// like the respective p_LmIs* routines, except that p might be empty
+PINLINE1 BOOLEAN p_IsConstantComp(const poly p, const ring r)
+{
+  if (p == NULL) return TRUE;
+  return (pNext(p)==NULL) && p_LmIsConstantComp(p, r);
+}
+
+PINLINE1 BOOLEAN p_IsConstant(const poly p, const ring r)
+{
+  if (p == NULL) return TRUE;
+  return (pNext(p)==NULL) && p_LmIsConstant(p, r);
+}
+
+PINLINE1 BOOLEAN p_IsUnit(const poly p, const ring r)
+{
+  if (p == NULL) return FALSE;
+  return p_LmIsConstant(p, r);
+}
+
+PINLINE1 BOOLEAN p_LmExpVectorAddIsOk(const poly p1, const poly p2,
+                                      const ring r)
+{
+  p_LmCheckPolyRing(p1, r);
+  p_LmCheckPolyRing(p2, r);
+  unsigned long l1, l2, divmask = r->divmask;
+  int i;
+
+  for (i=0; i<r->VarL_Size; i++)
+  {
+    l1 = p1->exp[r->VarL_Offset[i]];
+    l2 = p2->exp[r->VarL_Offset[i]];
+    // do the divisiblity trick
+    if ( (l1 > ULONG_MAX - l2) ||
+         (((l1 & divmask) ^ (l2 & divmask)) != ((l1 + l2) & divmask)))
+      return FALSE;
+  }
+  return TRUE;
+}
+
+#endif // !defined(NO_PINLINE1) || defined(PINLINE1_CC)
+#endif // PINLINE1_CC
Index: kernel/pInline2.cc
===================================================================
--- kernel/pInline2.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/pInline2.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,29 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pInline2.cc
+ *  Purpose: implementation of poly procs which are of constant time
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: pInline2.cc,v 1.1.1.1 2003-10-06 12:15:58 Singular Exp $
+ *******************************************************************/
+#ifndef PINLINE2_CC
+#define PINLINE2_CC
+#include "mod2.h"
+
+#ifdef PDEBUG
+
+#if PDEBUG < 2
+#undef PDEBUG
+#define PDEBUG 2
+#endif
+
+#undef NO_INLINE2
+#define NO_INLINE2 1
+
+#endif // PDEBUG
+
+#include "p_polys.h"
+
+#endif
Index: kernel/pInline2.h
===================================================================
--- kernel/pInline2.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/pInline2.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,724 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pInline2.h
+ *  Purpose: implementation of poly procs which are of constant time
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: pInline2.h,v 1.1.1.1 2003-10-06 12:15:52 Singular Exp $
+ *******************************************************************/
+#ifndef PINLINE2_H
+#define PINLINE2_H
+
+/***************************************************************
+ *
+ * Primitives for accessing and setting fields of a poly
+ *
+ ***************************************************************/
+#if !defined(NO_PINLINE2) || defined(PINLINE2_CC)
+
+#include "structs.h"
+#include "omalloc.h"
+#include "numbers.h"
+#include "p_Procs.h"
+#include "sbuckets.h"
+#ifdef HAVE_PLURAL
+#include "gring.h"
+#include "ring.h"
+#endif
+
+PINLINE2 number p_SetCoeff(poly p, number n, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  n_Delete(&(p->coef), r);
+  (p)->coef=n;
+  return n;
+}
+
+// order
+PINLINE2 Order_t p_GetOrder(poly p, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  if (r->typ==NULL) return ((p)->exp[r->pOrdIndex]);
+  int i=0;
+  loop
+  {
+    switch(r->typ[i].ord_typ)
+    {
+      case ro_wp_neg:
+        return (((long)((p)->exp[r->pOrdIndex]))-((long) POLY_NEGWEIGHT_OFFSET));
+      case ro_syzcomp:
+      case ro_syz:
+      case ro_cp:
+        i++;
+        break;
+      //case ro_dp:
+      //case ro_wp:
+      default:
+        return ((p)->exp[r->pOrdIndex]);
+    }
+  }
+}
+
+PINLINE2 Order_t p_SetOrder(poly p, long o, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  pAssume2(o >= 0);
+  if (r->typ==NULL) return ((p)->exp[r->pOrdIndex]=o);
+  int i=0;
+  loop
+  {
+    switch(r->typ[i].ord_typ)
+    {
+      case ro_wp_neg:
+        return (p)->exp[r->pOrdIndex]=o+POLY_NEGWEIGHT_OFFSET;
+      case ro_syzcomp:
+      case ro_syz:
+      case ro_cp:
+        i++;
+        break;
+      //case ro_dp:
+      //case ro_wp:
+      default:
+        return (p)->exp[r->pOrdIndex] = o;
+    }
+  }
+}
+
+// Setm
+PINLINE2 void p_Setm(poly p, ring r)
+{
+  p_CheckRing2(r);
+  r->p_Setm(p, r);
+}
+
+// component
+PINLINE2  unsigned long p_SetComp(poly p, unsigned long c, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  pAssume2(rRing_has_Comp(r));
+  __p_GetComp(p,r) = c;
+  return c;
+}
+PINLINE2 unsigned long p_IncrComp(poly p, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  pAssume2(rRing_has_Comp(r));
+  return ++(__p_GetComp(p,r));
+}
+PINLINE2 unsigned long p_DecrComp(poly p, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  pAssume2(rRing_has_Comp(r));
+  pPolyAssume2(__p_GetComp(p,r) > 0);
+  return --(__p_GetComp(p,r));
+}
+PINLINE2 unsigned long p_AddComp(poly p, unsigned long v, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  pAssume2(rRing_has_Comp(r));
+  return __p_GetComp(p,r) += v;
+}
+PINLINE2 unsigned long p_SubComp(poly p, unsigned long v, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  pAssume2(rRing_has_Comp(r));
+  pPolyAssume2(__p_GetComp(p,r) >= v);
+  return __p_GetComp(p,r) -= v;
+}
+
+// exponent
+// r->VarOffset encodes the position in p->exp (lower 24 bits)
+// and number of bits to shift to the right in the upper 8 bits
+PINLINE2 int p_GetExp(poly p, int v, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  pAssume2(v > 0 && v <= r->N);
+#if 0
+  int pos=(r->VarOffset[v] & 0xffffff);
+  int bitpos=(r->VarOffset[v] >> 24);
+  int exp=(p->exp[pos] >> bitmask) & r->bitmask;
+  return exp;
+#else
+  return (int)
+         ((p->exp[(r->VarOffset[v] & 0xffffff)] >> (r->VarOffset[v] >> 24))
+          & r->bitmask);
+#endif
+}
+PINLINE2 int p_SetExp(poly p, int v, int e, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  pAssume2(v>0 && v <= r->N);
+  pAssume2(e>=0);
+  pAssume2((unsigned int) e<=r->bitmask);
+
+  // shift e to the left:
+  register int shift = r->VarOffset[v] >> 24;
+  unsigned long ee = ((unsigned long)e) << shift /*(r->VarOffset[v] >> 24)*/;
+  // find the bits in the exponent vector
+  register int offset = (r->VarOffset[v] & 0xffffff);
+  // clear the bits in the exponent vector:
+  p->exp[offset]  &= ~( r->bitmask << shift );
+  // insert e with |
+  p->exp[ offset ] |= ee;
+  return e;
+}
+
+// the following should be implemented more efficiently
+PINLINE2  int p_IncrExp(poly p, int v, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  int e = p_GetExp(p,v,r);
+  e++;
+  return p_SetExp(p,v,e,r);
+}
+PINLINE2  int p_DecrExp(poly p, int v, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  int e = p_GetExp(p,v,r);
+  pAssume2(e > 0);
+  e--;
+  return p_SetExp(p,v,e,r);
+}
+PINLINE2  int p_AddExp(poly p, int v, int ee, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  int e = p_GetExp(p,v,r);
+  e += ee;
+  return p_SetExp(p,v,e,r);
+}
+PINLINE2  int p_SubExp(poly p, int v, int ee, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  int e = p_GetExp(p,v,r);
+  pAssume2(e >= ee);
+  e -= ee;
+  return p_SetExp(p,v,e,r);
+}
+PINLINE2  int p_MultExp(poly p, int v, int ee, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  int e = p_GetExp(p,v,r);
+  e *= ee;
+  return p_SetExp(p,v,e,r);
+}
+
+PINLINE2 int p_GetExpSum(poly p1, poly p2, int i, ring r)
+{
+  p_LmCheckPolyRing2(p1, r);
+  p_LmCheckPolyRing2(p2, r);
+  return p_GetExp(p1,i,r) + p_GetExp(p2,i,r);
+}
+PINLINE2 int p_GetExpDiff(poly p1, poly p2, int i, ring r)
+{
+  return p_GetExp(p1,i,r) - p_GetExp(p2,i,r);
+}
+
+
+/***************************************************************
+ *
+ * Allocation/Initalization/Deletion
+ *
+ ***************************************************************/
+PINLINE2 poly p_New(ring r, omBin bin)
+{
+  p_CheckRing2(r);
+  pAssume2(bin != NULL && r->PolyBin->sizeW == bin->sizeW);
+  poly p;
+  omTypeAllocBin(poly, p, bin);
+  p_SetRingOfLm(p, r);
+  return p;
+}
+
+PINLINE2 poly p_New(ring r)
+{
+  return p_New(r, r->PolyBin);
+}
+
+PINLINE2 void p_DeleteLm(poly *p, ring r)
+{
+  pIfThen2(*p != NULL, p_LmCheckPolyRing2(*p, r));
+  poly h = *p;
+  if (h != NULL)
+  {
+    n_Delete(&_pGetCoeff(h), r);
+    *p = _pNext(h);
+    omFreeBinAddr(h);
+  }
+}
+PINLINE2 void p_DeleteLm(poly p, ring r)
+{
+  pIfThen2(p != NULL, p_LmCheckPolyRing2(p, r));
+  if (p != NULL)
+  {
+    n_Delete(&_pGetCoeff(p), r);
+    omFreeBinAddr(p);
+  }
+}
+PINLINE2 void p_LmFree(poly p, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  omFreeBinAddr(p);
+}
+PINLINE2 void p_LmFree(poly *p, ring r)
+{
+  p_LmCheckPolyRing2(*p, r);
+  poly h = *p;
+  *p = pNext(h);
+  omFreeBinAddr(h);
+}
+PINLINE2 poly p_LmFreeAndNext(poly p, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  poly pnext = pNext(p);
+  omFreeBinAddr(p);
+  return pnext;
+}
+PINLINE2 void p_LmDelete(poly p, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  n_Delete(&_pGetCoeff(p), r);
+  omFreeBinAddr(p);
+}
+PINLINE2 void p_LmDelete(poly *p, ring r)
+{
+  p_LmCheckPolyRing2(*p, r);
+  poly h = *p;
+  *p = pNext(h);
+  n_Delete(&pGetCoeff(h), r);
+  omFreeBinAddr(h);
+}
+PINLINE2 poly p_LmDeleteAndNext(poly p, ring r)
+{
+  p_LmCheckPolyRing2(p, r);
+  poly pnext = _pNext(p);
+  n_Delete(&_pGetCoeff(p), r);
+  omFreeBinAddr(p);
+  return pnext;
+}
+
+/***************************************************************
+ *
+ * Misc routines
+ *
+ ***************************************************************/
+PINLINE2 int p_Cmp(poly p1, poly p2, ring r)
+{
+  if (p2==NULL)
+    return 1;
+  if (p1==NULL)
+    return -1;
+  return p_LmCmp(p1,p2,r);
+}
+
+PINLINE2 unsigned long p_GetMaxExp(poly p, ring r)
+{
+  return p_GetMaxExp(p_GetMaxExpL(p, r), r);
+}
+
+PINLINE2 unsigned long
+p_GetMaxExp(const unsigned long l, const ring r, const int number_of_exps)
+{
+  unsigned long bitmask = r->bitmask;
+  unsigned long max = (l & bitmask);
+  unsigned long j = number_of_exps - 1;
+
+  if (j > 0)
+  {
+    unsigned long i = r->BitsPerExp;
+    long e;
+    loop
+    {
+      e = ((l >> i) & bitmask);
+      if ((unsigned long) e > max)
+        max = e;
+      j--;
+      if (j==0) break;
+      i += r->BitsPerExp;
+    }
+  }
+  return max;
+}
+
+PINLINE2 unsigned long p_GetMaxExp(const unsigned long l, const ring r)
+{
+  return p_GetMaxExp(l, r, r->ExpPerLong);
+}
+
+PINLINE2 unsigned long
+p_GetTotalDegree(const unsigned long l, const ring r, const int number_of_exps)
+{
+  const unsigned long bitmask = r->bitmask;
+  unsigned long sum = (l & bitmask);
+  unsigned long j = number_of_exps - 1;
+
+  if (j > 0)
+  {
+    unsigned long i = r->BitsPerExp;
+    loop
+    {
+      sum += ((l >> i) & bitmask);
+      j--;
+      if (j==0) break;
+      i += r->BitsPerExp;
+    }
+  }
+  return sum;
+}
+
+PINLINE2 unsigned long
+p_GetTotalDegree(const unsigned long l, const ring r)
+{
+  return p_GetTotalDegree(l, r, r->ExpPerLong);
+}
+
+/***************************************************************
+ *
+ * Dispatcher to r->p_Procs, they do the tests/checks
+ *
+ ***************************************************************/
+// returns a copy of p
+PINLINE2 poly p_Copy(poly p, const ring r)
+{
+  return r->p_Procs->p_Copy(p, r);
+}
+
+PINLINE2 poly p_Copy(poly p, const ring lmRing, const ring tailRing)
+{
+#ifndef PDEBUG
+  if (tailRing == lmRing)
+    return tailRing->p_Procs->p_Copy(p, tailRing);
+#endif
+  if (p != NULL)
+  {
+    poly pres = p_Head(p, lmRing);
+    pNext(pres) = tailRing->p_Procs->p_Copy(pNext(p), tailRing);
+    return pres;
+  }
+  else
+    return NULL;
+}
+
+// deletes *p, and sets *p to NULL
+PINLINE2 void p_Delete(poly *p, const ring r)
+{
+  r->p_Procs->p_Delete(p, r);
+}
+
+PINLINE2 void p_Delete(poly *p,  const ring lmRing, const ring tailRing)
+{
+#ifndef PDEBUG
+  if (tailRing == lmRing)
+  {
+    tailRing->p_Procs->p_Delete(p, tailRing);
+    return;
+  }
+#endif
+  if (*p != NULL)
+  {
+    if (pNext(*p) != NULL)
+      tailRing->p_Procs->p_Delete(&pNext(*p), tailRing);
+    p_LmDelete(p, lmRing);
+  }
+}
+
+PINLINE2 poly p_ShallowCopyDelete(poly p, const ring r, omBin bin)
+{
+  p_LmCheckPolyRing2(p, r);
+  pAssume2(r->PolyBin->sizeW == bin->sizeW);
+  return r->p_Procs->p_ShallowCopyDelete(p, r, bin);
+}
+
+// returns p+q, destroys p and q
+PINLINE2 poly p_Add_q(poly p, poly q, const ring r)
+{
+  int shorter;
+  return r->p_Procs->p_Add_q(p, q, shorter, r);
+}
+
+PINLINE2 poly p_Add_q(poly p, poly q, int &lp, int lq, const ring r)
+{
+  int shorter;
+  poly res = r->p_Procs->p_Add_q(p, q, shorter, r);
+  lp = (lp + lq) - shorter;
+  return res;
+}
+
+// returns p*n, destroys p
+PINLINE2 poly p_Mult_nn(poly p, number n, const ring r)
+{
+  if (n_IsOne(n, r))
+    return p;
+  else
+    return r->p_Procs->p_Mult_nn(p, n, r);
+}
+
+PINLINE2 poly p_Mult_nn(poly p, number n, const ring lmRing,
+                        const ring tailRing)
+{
+#ifndef PDEBUG
+  if (lmRing == tailRing)
+  {
+    return p_Mult_nn(p, n, tailRing);
+  }
+#endif
+  poly pnext = pNext(p);
+  pNext(p) = NULL;
+  p = lmRing->p_Procs->p_Mult_nn(p, n, lmRing);
+  pNext(p) = tailRing->p_Procs->p_Mult_nn(pnext, n, tailRing);
+  return p;
+}
+
+// returns p*n, does not destroy p
+PINLINE2 poly pp_Mult_nn(poly p, number n, const ring r)
+{
+  if (n_IsOne(n, r))
+    return p_Copy(p, r);
+  else
+    return r->p_Procs->pp_Mult_nn(p, n, r);
+}
+
+// returns Copy(p)*m, does neither destroy p nor m
+PINLINE2 poly pp_Mult_mm(poly p, poly m, const ring r)
+{
+  if (p_LmIsConstant(m, r))
+    return pp_Mult_nn(p, pGetCoeff(m), r);
+  else
+  {
+    poly last;
+#ifdef HAVE_PLURAL
+    if (rIsPluralRing(r))
+      return nc_pp_Mult_mm(p, m, r, last);
+#endif
+    return r->p_Procs->pp_Mult_mm(p, m, r, last);
+  }
+}
+
+// returns p*m, destroys p, const: m
+PINLINE2 poly p_Mult_mm(poly p, poly m, const ring r)
+{
+  if (p_LmIsConstant(m, r))
+    return p_Mult_nn(p, pGetCoeff(m), r);
+  else
+#ifdef HAVE_PLURAL
+    if (rIsPluralRing(r))
+      return nc_p_Mult_mm(p, m, r);
+#endif
+    return r->p_Procs->p_Mult_mm(p, m, r);
+}
+
+// return p - m*Copy(q), destroys p; const: p,m
+PINLINE2 poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, const ring r)
+{
+  int shorter;
+  poly last;
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(r))
+    return nc_p_Minus_mm_Mult_qq(p, m, q, r);
+#endif
+  return r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, NULL, r, last);
+}
+PINLINE2 poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,
+                                 poly spNoether, const ring r)
+{
+  int shorter;
+  poly last,res;
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(r))
+  {
+     res = nc_p_Minus_mm_Mult_qq(p, m, q, r);
+     lp = pLength(res);
+  }
+  else
+#endif
+  {
+    res = r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, spNoether, r, last);
+    lp = (lp + lq) - shorter;
+  }
+  return res;
+}
+
+PINLINE2 poly pp_Mult_Coeff_mm_DivSelect(poly p, const poly m, const ring r)
+{
+  int shorter;
+  return r->p_Procs->pp_Mult_Coeff_mm_DivSelect(p, m, shorter, r);
+}
+
+PINLINE2 poly pp_Mult_Coeff_mm_DivSelect(poly p, int &lp, const poly m, const ring r)
+{
+  int shorter;
+  poly pp = r->p_Procs->pp_Mult_Coeff_mm_DivSelect(p, m, shorter, r);
+  lp -= shorter;
+  return pp;
+}
+
+// returns -p, destroys p
+PINLINE2 poly p_Neg(poly p, const ring r)
+{
+  return r->p_Procs->p_Neg(p, r);
+}
+
+extern poly  _p_Mult_q(poly p, poly q, const int copy, const ring r);
+// returns p*q, destroys p and q
+PINLINE2 poly p_Mult_q(poly p, poly q, const ring r)
+{
+  if (p == NULL)
+  {
+    r->p_Procs->p_Delete(&q, r);
+    return NULL;
+  }
+  if (q == NULL)
+  {
+    r->p_Procs->p_Delete(&p, r);
+    return NULL;
+  }
+
+  if (pNext(p) == NULL)
+  {
+#ifdef HAVE_PLURAL
+    if (rIsPluralRing(r))
+      q = nc_mm_Mult_p(p, q, r);
+    else
+#endif /* HAVE_PLURAL */
+      q = r->p_Procs->p_Mult_mm(q, p, r);
+
+    r->p_Procs->p_Delete(&p, r);
+    return q;
+  }
+
+  if (pNext(q) == NULL)
+  {
+#ifdef HAVE_PLURAL
+    if (rIsPluralRing(r))
+      p = nc_p_Mult_mm(p, q, r);
+    else
+#endif /* HAVE_PLURAL */
+      p = r->p_Procs->p_Mult_mm(p, q, r);
+
+    r->p_Procs->p_Delete(&q, r);
+    return p;
+  }
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(r))
+    return _nc_p_Mult_q(p, q, 0, r);
+  else
+#endif
+  return _p_Mult_q(p, q, 0, r);
+}
+
+// returns p*q, does neither destroy p nor q
+PINLINE2 poly pp_Mult_qq(poly p, poly q, const ring r)
+{
+  poly last;
+  if (p == NULL || q == NULL) return NULL;
+
+  if (pNext(p) == NULL)
+  {
+#ifdef HAVE_PLURAL
+    if (rIsPluralRing(r))
+      return nc_mm_Mult_p(p, p_Copy(q,r), r);
+#endif
+    return r->p_Procs->pp_Mult_mm(q, p, r, last);
+  }
+
+  if (pNext(q) == NULL)
+  {
+#ifdef HAVE_PLURAL
+    if (rIsPluralRing(r))
+      return nc_p_Mult_mm(p_Copy(p,r), q, r);
+#endif
+    return r->p_Procs->pp_Mult_mm(p, q, r, last);
+  }
+
+  poly qq = q;
+  if (p == q)
+    qq = p_Copy(q, r);
+
+  poly res;
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(r))
+    res = _nc_p_Mult_q(p, qq, 1, r);
+  else
+#endif
+    res = _p_Mult_q(p, qq, 1, r);
+
+  if (qq != q)
+    p_Delete(&qq, r);
+  return res;
+}
+
+// returns p + m*q destroys p, const: q, m
+// this should be implemented more efficiently
+PINLINE2 poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,
+                                const ring r)
+{
+  poly res, last;
+  int shorter;
+  number n_old = pGetCoeff(m);
+  number n_neg = n_Copy(n_old, r);
+  n_neg = n_Neg(n_neg, r);
+  pSetCoeff0(m, n_neg);
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(r))
+    res = nc_p_Minus_mm_Mult_qq(p, m, q, r);
+  else
+#endif
+    res = r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, NULL, r, last);
+
+  lp = (lp + lq) - shorter;
+  pSetCoeff0(m, n_old);
+  n_Delete(&n_neg, r);
+  return res;
+}
+
+PINLINE2 poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, const ring r)
+{
+  int lp = 0, lq = 0;
+  return p_Plus_mm_Mult_qq(p, m, q, lp, lq, r);
+}
+
+PINLINE2 poly p_Merge_q(poly p, poly q, const ring r)
+{
+  return r->p_Procs->p_Merge_q(p, q, r);
+}
+
+PINLINE2 poly p_SortAdd(poly p, const ring r, BOOLEAN revert)
+{
+  if (revert) p = pReverse(p);
+  return sBucketSortAdd(p, r);
+}
+
+PINLINE2 poly p_SortMerge(poly p, const ring r, BOOLEAN revert)
+{
+  if (revert) p = pReverse(p);
+  return sBucketSortMerge(p, r);
+}
+
+/***************************************************************
+ *
+ * I/O
+ *
+ ***************************************************************/
+PINLINE2 char*     p_String(poly p, ring p_ring)
+{
+  return p_String(p, p_ring, p_ring);
+}
+PINLINE2 char*     p_String0(poly p, ring p_ring)
+{
+  return p_String0(p, p_ring, p_ring);
+}
+PINLINE2 void      p_Write(poly p, ring p_ring)
+{
+  p_Write(p, p_ring, p_ring);
+}
+PINLINE2 void      p_Write0(poly p, ring p_ring)
+{
+  p_Write0(p, p_ring, p_ring);
+}
+PINLINE2 void      p_wrp(poly p, ring p_ring)
+{
+  p_wrp(p, p_ring, p_ring);
+}
+#endif // !defined(NO_PINLINE2) || defined(POLYS_IMPL_CC)
+#endif // PINLINE2_H
Index: kernel/pShallowCopyDelete.cc
===================================================================
--- kernel/pShallowCopyDelete.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/pShallowCopyDelete.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,54 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pShallowCopyDelete.cc
+ *  Purpose: implementation of pShallowCopyDelete routines
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: pShallowCopyDelete.cc,v 1.1.1.1 2003-10-06 12:15:58 Singular Exp $
+ *******************************************************************/
+#include "mod2.h"
+#include "p_polys.h"
+#include "ring.h"
+#include "pShallowCopyDelete.h"
+
+// a simple implementations
+poly pShallowCopyDelete_General(poly s_p, ring s_r, ring d_r, omBin d_bin)
+{
+  p_CheckPolyRing(s_p, s_r);
+  p_CheckRing(d_r);
+  assume(d_bin != NULL);
+  assume(d_bin == d_r->PolyBin || d_bin->sizeW == d_r->PolyBin->sizeW);
+  assume(s_r->N == d_r->N);
+
+  spolyrec dp;
+  poly d_p = &dp;
+  int N = d_r->N;
+  int i;
+
+
+  while (s_p != NULL)
+  {
+    d_p->next = p_Init(d_r, d_bin);
+    pIter(d_p);
+
+    pSetCoeff0(d_p, pGetCoeff(s_p));
+    for (i=1; i<= N; i++)
+      p_SetExp(d_p, i, p_GetExp(s_p, i, s_r), d_r);
+
+    if (rRing_has_Comp(d_r))
+      p_SetComp(d_p, p_GetComp(s_p, s_r), d_r);
+    p_Setm(d_p, d_r);
+
+    s_p = p_LmFreeAndNext(s_p, s_r);
+  }
+  pNext(d_p) = NULL;
+
+  return dp.next;
+}
+
+pShallowCopyDeleteProc pGetShallowCopyDeleteProc(ring source_r, ring dest_r)
+{
+  return pShallowCopyDelete_General;
+}
Index: kernel/pShallowCopyDelete.h
===================================================================
--- kernel/pShallowCopyDelete.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/pShallowCopyDelete.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,17 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pShallowCopyDelete.cc
+ *  Purpose: implementation of pShallowCopyDelete routines
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: pShallowCopyDelete.h,v 1.1.1.1 2003-10-06 12:15:58 Singular Exp $
+ *******************************************************************/
+
+// returns a poly from dest_r which is a ShallowCopy of s_p from source_r
+// assumes that source_r->N == dest_r->N and that orderings are the same
+typedef poly (*pShallowCopyDeleteProc)(poly s_p, ring source_r, ring dest_r, 
+                                       omBin dest_bin);
+pShallowCopyDeleteProc pGetShallowCopyDeleteProc(ring source_r, ring dest_r);
+
Index: kernel/p_Add_q__T.cc
===================================================================
--- kernel/p_Add_q__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Add_q__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,89 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Add_q__Template.cc
+ *  Purpose: template for p_Add_q
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_Add_q__T.cc,v 1.1.1.1 2003-10-06 12:15:58 Singular Exp $
+ *******************************************************************/
+
+/***************************************************************
+ *
+ * Returns:  p + q,
+ *           Shorter, where Shorter == Length(p) + Length(q) - Length(p+q);
+ * Destroys: p, q
+ *
+ ***************************************************************/
+LINKAGE poly p_Add_q(poly p, poly q, int &Shorter, const ring r)
+{
+  p_Test(p, r);
+  p_Test(q, r);
+#if PDEBUG > 0
+  int l = pLength(p) + pLength(q);
+#endif
+
+  // test for trivial cases
+  Shorter = 0;
+  if (q == NULL) return p;
+  if (p == NULL) return q;
+
+  number t, n1, n2;
+  int shorter = 0;
+  spolyrec rp;
+  poly a = &rp;
+  DECLARE_LENGTH(const unsigned long length = r->CmpL_Size);
+  DECLARE_ORDSGN(const long* ordsgn = r->ordsgn);
+
+  Top:     // compare p and q w.r.t. monomial ordering
+  p_MemCmp(p->exp, q->exp, length, ordsgn, goto Equal, goto Greater , goto Smaller);
+
+  Equal:
+  n1 = pGetCoeff(p);
+  n2 = pGetCoeff(q);
+  t = n_Add(n1,n2, r);
+  n_Delete(&n1, r);
+  n_Delete(&n2, r);
+  q = p_LmFreeAndNext(q, r);
+
+  if (n_IsZero(t, r))
+  {
+    shorter += 2;
+    n_Delete(&t, r);
+    p = p_LmFreeAndNext(p, r);
+  }
+  else
+  {
+    shorter++;
+    pSetCoeff0(p,t);
+    a = pNext(a) = p;
+    pIter(p);
+  }
+  if (p==NULL) { pNext(a) = q; goto Finish;}
+  if (q==NULL) { pNext(a) = p; goto Finish;}
+  goto Top;
+
+  Greater:
+  a = pNext(a) = p;
+  pIter(p);
+  if (p==NULL) { pNext(a) = q; goto Finish;}
+  goto Top;
+
+  Smaller:
+  a = pNext(a) = q;
+  pIter(q);
+  if (q==NULL) { pNext(a) = p; goto Finish;}
+  goto Top;
+
+
+  Finish:
+  Shorter = shorter;
+
+  p_Test(pNext(&rp), r);
+#if PDEBUG > 0
+  pAssume1(l - pLength(pNext(&rp)) == Shorter);
+#endif
+  return pNext(&rp);
+}
+
Index: kernel/p_Copy__T.cc
===================================================================
--- kernel/p_Copy__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Copy__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,38 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Copy__Template.cc
+ *  Purpose: template for p_Copy
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_Copy__T.cc,v 1.1.1.1 2003-10-06 12:15:59 Singular Exp $
+ *******************************************************************/
+
+LINKAGE poly p_Copy(poly s_p, const ring r)
+{
+  // let's not do tests here -- but instead allow
+  // to be sloppy
+  spolyrec dp;
+  poly d_p = &dp;
+  omBin bin = r->PolyBin;
+  poly h;
+
+  DECLARE_LENGTH(const unsigned long length = r->ExpL_Size);
+
+  while (s_p != NULL)
+  {
+    p_AllocBin(pNext(d_p), bin, r);
+    pIter(d_p);
+    pSetCoeff0(d_p, n_Copy(pGetCoeff(s_p), r));
+    // it is better to iter here,
+    // for MemCopy advances goes from low to high addresses
+    h = s_p;
+    s_p = pNext(s_p);
+    p_MemCopy(d_p->exp, h->exp, length);
+  }
+  pNext(d_p) = NULL;
+
+  return dp.next;
+}
+
Index: kernel/p_Delete__T.cc
===================================================================
--- kernel/p_Delete__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Delete__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,23 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Delete__Template.cc
+ *  Purpose: template for p_Delete
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_Delete__T.cc,v 1.1.1.1 2003-10-06 12:15:59 Singular Exp $
+ *******************************************************************/
+
+LINKAGE void p_Delete(poly* pp, const ring r)
+{
+  poly p = *pp;
+
+  while (p != NULL)
+  {
+    n_Delete(&(p->coef), r);
+    p = p_LmFreeAndNext(p, r);
+  }
+  *pp = NULL;
+}
+
Index: kernel/p_MemAdd.h
===================================================================
--- kernel/p_MemAdd.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_MemAdd.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,389 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_MemAdd.h
+ *  Purpose: macros for memory addition
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_MemAdd.h,v 1.1.1.1 2003-10-06 12:15:59 Singular Exp $
+ *******************************************************************/
+#ifndef P_MEM_ADD_H
+#define P_MEM_ADD_H
+
+/***************************************************************
+ *
+ * MemSum
+ *
+ ***************************************************************/
+
+#define _p_MemSum(i, r, s1, s2) r[i] = s1[i] + s2[i]
+
+#define _p_MemSum_LengthOne(r, s1, s2) _p_MemSum(0, r, s1, s2)
+#define _p_MemSum_LengthTwo(r, s1, s2) do{_p_MemSum_LengthOne(r, s1, s2); _p_MemSum(1, r, s1, s2);} while(0)
+#define _p_MemSum_LengthThree(r, s1, s2) do{_p_MemSum_LengthTwo(r, s1, s2); _p_MemSum(2, r, s1, s2);} while(0)
+#define _p_MemSum_LengthFour(r, s1, s2) do{_p_MemSum_LengthThree(r, s1, s2); _p_MemSum(3, r, s1, s2);} while(0)
+#define _p_MemSum_LengthFive(r, s1, s2) do{_p_MemSum_LengthFour(r, s1, s2); _p_MemSum(4, r, s1, s2);} while(0)
+#define _p_MemSum_LengthSix(r, s1, s2) do{_p_MemSum_LengthFive(r, s1, s2); _p_MemSum(5, r, s1, s2);} while(0)
+#define _p_MemSum_LengthSeven(r, s1, s2) do{_p_MemSum_LengthSix(r, s1, s2); _p_MemSum(6, r, s1, s2);} while(0)
+#define _p_MemSum_LengthEight(r, s1, s2) do{_p_MemSum_LengthSeven(r, s1, s2); _p_MemSum(7, r, s1, s2);} while(0)
+
+#define _p_MemSum_Declare(r, s1, s2)                \
+  const unsigned long* _s1 = ((unsigned long*) s1); \
+  const unsigned long* _s2 = ((unsigned long*) s2); \
+  unsigned long* _r = ((unsigned long*) r)
+
+#define p_MemSum_LengthOne(r, s1, s2, length) _p_MemSum_LengthOne(r, s1, s2)
+#define p_MemSum_LengthTwo(r, s1, s2, length)   \
+do                                              \
+{                                               \
+  _p_MemSum_Declare(r,s1,s2);                    \
+  _p_MemSum_LengthTwo(_r, _s1, _s2);            \
+}                                               \
+while (0)
+#define p_MemSum_LengthThree(r, s1, s2, length) \
+do                                              \
+{                                               \
+  _p_MemSum_Declare(r,s1,s2);                    \
+  _p_MemSum_LengthThree(_r, _s1, _s2);          \
+}                                               \
+while (0)
+#define p_MemSum_LengthFour(r, s1, s2, length)  \
+do                                              \
+{                                               \
+  _p_MemSum_Declare(r,s1,s2);                    \
+  _p_MemSum_LengthFour(_r, _s1, _s2);           \
+}                                               \
+while (0)
+#define p_MemSum_LengthFive(r, s1, s2, length)  \
+do                                              \
+{                                               \
+  _p_MemSum_Declare(r,s1,s2);                    \
+  _p_MemSum_LengthFive(_r, _s1, _s2);           \
+}                                               \
+while (0)
+#define p_MemSum_LengthSix(r, s1, s2, length)   \
+do                                              \
+{                                               \
+  _p_MemSum_Declare(r,s1,s2);                    \
+  _p_MemSum_LengthSix(_r, _s1, _s2);            \
+}                                               \
+while (0)
+#define p_MemSum_LengthSeven(r, s1, s2, length) \
+do                                              \
+{                                               \
+  _p_MemSum_Declare(r,s1,s2);                    \
+  _p_MemSum_LengthSeven(_r, _s1, _s2);          \
+}                                               \
+while (0)
+#define p_MemSum_LengthEight(r, s1, s2, length) \
+do                                              \
+{                                               \
+  _p_MemSum_Declare(r,s1,s2);                    \
+  _p_MemSum_LengthEight(_r, _s1, _s2);          \
+}                                               \
+while (0)
+
+#define p_MemSum_LengthGeneral(r, s1, s2, length)   \
+do                                                  \
+{                                                   \
+  _p_MemSum_Declare(r,s1,s2);                       \
+  const unsigned long _l = (unsigned long) length;       \
+  unsigned long _i = 0;                             \
+                                                    \
+  do                                                \
+  {                                                 \
+    _r[_i] = _s1[_i] + _s2[_i];                     \
+    _i++;                                           \
+  }                                                 \
+  while (_i != _l);                                 \
+}                                                   \
+while (0)
+
+/***************************************************************
+ *
+ * MemAdd
+ *
+ ***************************************************************/
+#define _p_MemAdd(i, r, s) r[i] += s[i]
+
+#define _p_MemAdd_LengthOne(r, s) _p_MemAdd(0, r, s)
+#define _p_MemAdd_LengthTwo(r, s) do{_p_MemAdd_LengthOne(r, s); _p_MemAdd(1, r, s);} while(0)
+#define _p_MemAdd_LengthThree(r, s) do{_p_MemAdd_LengthTwo(r, s); _p_MemAdd(2, r, s);} while(0)
+#define _p_MemAdd_LengthFour(r, s) do{_p_MemAdd_LengthThree(r, s); _p_MemAdd(3, r, s);} while(0)
+#define _p_MemAdd_LengthFive(r, s) do{_p_MemAdd_LengthFour(r, s); _p_MemAdd(4, r, s);} while(0)
+#define _p_MemAdd_LengthSix(r, s) do{_p_MemAdd_LengthFive(r, s); _p_MemAdd(5, r, s);} while(0)
+#define _p_MemAdd_LengthSeven(r, s) do{_p_MemAdd_LengthSix(r, s); _p_MemAdd(6, r, s);} while(0)
+#define _p_MemAdd_LengthEight(r, s) do{_p_MemAdd_LengthSeven(r, s); _p_MemAdd(7, r, s);} while(0)
+
+#define _p_MemAdd_Declare(r, s)                \
+  const unsigned long* _s = ((unsigned long*) s); \
+  unsigned long* _r = ((unsigned long*) r)
+
+#define p_MemAdd_LengthOne(r, s, length) _p_MemAdd_LengthOne(r, s)
+#define p_MemAdd_LengthTwo(r, s, length)   \
+do                                              \
+{                                               \
+  _p_MemAdd_Declare(r,s);                    \
+  _p_MemAdd_LengthTwo(_r, _s);            \
+}                                               \
+while (0)
+#define p_MemAdd_LengthThree(r, s, length) \
+do                                              \
+{                                               \
+  _p_MemAdd_Declare(r,s);                    \
+  _p_MemAdd_LengthThree(_r, _s);          \
+}                                               \
+while (0)
+#define p_MemAdd_LengthFour(r, s, length)  \
+do                                              \
+{                                               \
+  _p_MemAdd_Declare(r,s);                    \
+  _p_MemAdd_LengthFour(_r, _s);           \
+}                                               \
+while (0)
+#define p_MemAdd_LengthFive(r, s, length)  \
+do                                              \
+{                                               \
+  _p_MemAdd_Declare(r,s);                    \
+  _p_MemAdd_LengthFive(_r, _s);           \
+}                                               \
+while (0)
+#define p_MemAdd_LengthSix(r, s, length)   \
+do                                              \
+{                                               \
+  _p_MemAdd_Declare(r,s);                    \
+  _p_MemAdd_LengthSix(_r, _s);            \
+}                                               \
+while (0)
+#define p_MemAdd_LengthSeven(r, s, length) \
+do                                              \
+{                                               \
+  _p_MemAdd_Declare(r,s);                    \
+  _p_MemAdd_LengthSeven(_r, _s);          \
+}                                               \
+while (0)
+#define p_MemAdd_LengthEight(r, s, length) \
+do                                              \
+{                                               \
+  _p_MemAdd_Declare(r,s);                    \
+  _p_MemAdd_LengthEight(_r, _s);          \
+}                                               \
+while (0)
+
+#define p_MemAdd_LengthGeneral(r, s, length)       \
+do                                                  \
+{                                                   \
+  _p_MemAdd_Declare(r,s);                          \
+  const unsigned long _l = (unsigned long) length;  \
+  unsigned long _i = 0;                             \
+                                                    \
+  do                                                \
+  {                                                 \
+    _r[_i] += _s[_i];                               \
+    _i++;                                           \
+  }                                                 \
+  while (_i != _l);                                 \
+}                                                   \
+while (0)
+
+
+/***************************************************************
+ *
+ * MemDiff
+ *
+ ***************************************************************/
+#define _p_MemDiff(i, r, s1, s2) r[i] = s1[i] - s2[i]
+
+#define _p_MemDiff_LengthOne(r, s1, s2) _p_MemDiff(0, r, s1, s2)
+#define _p_MemDiff_LengthTwo(r, s1, s2) do{_p_MemDiff_LengthOne(r, s1, s2); _p_MemDiff(1, r, s1, s2);} while(0)
+#define _p_MemDiff_LengthThree(r, s1, s2) do{_p_MemDiff_LengthTwo(r, s1, s2); _p_MemDiff(2, r, s1, s2);} while(0)
+#define _p_MemDiff_LengthFour(r, s1, s2) do{_p_MemDiff_LengthThree(r, s1, s2); _p_MemDiff(3, r, s1, s2);} while(0)
+#define _p_MemDiff_LengthFive(r, s1, s2) do{_p_MemDiff_LengthFour(r, s1, s2); _p_MemDiff(4, r, s1, s2);} while(0)
+#define _p_MemDiff_LengthSix(r, s1, s2) do{_p_MemDiff_LengthFive(r, s1, s2); _p_MemDiff(5, r, s1, s2);} while(0)
+#define _p_MemDiff_LengthSeven(r, s1, s2) do{_p_MemDiff_LengthSix(r, s1, s2); _p_MemDiff(6, r, s1, s2);} while(0)
+#define _p_MemDiff_LengthEight(r, s1, s2) do{_p_MemDiff_LengthSeven(r, s1, s2); _p_MemDiff(7, r, s1, s2);} while(0)
+
+#define _p_MemDiff_Declare(r, s1, s2)                \
+  const unsigned long* _s1 = ((unsigned long*) s1); \
+  const unsigned long* _s2 = ((unsigned long*) s2); \
+  unsigned long* _r = ((unsigned long*) r)
+
+#define p_MemDiff_LengthOne(r, s1, s2, length) _p_MemDiff_LengthOne(r, s1, s2)
+#define p_MemDiff_LengthTwo(r, s1, s2, length)   \
+do                                              \
+{                                               \
+  _p_MemDiff_Declare(r,s1,s2);                    \
+  _p_MemDiff_LengthTwo(_r, _s1, _s2);            \
+}                                               \
+while (0)
+#define p_MemDiff_LengthThree(r, s1, s2, length) \
+do                                              \
+{                                               \
+  _p_MemDiff_Declare(r,s1,s2);                    \
+  _p_MemDiff_LengthThree(_r, _s1, _s2);          \
+}                                               \
+while (0)
+#define p_MemDiff_LengthFour(r, s1, s2, length)  \
+do                                              \
+{                                               \
+  _p_MemDiff_Declare(r,s1,s2);                    \
+  _p_MemDiff_LengthFour(_r, _s1, _s2);           \
+}                                               \
+while (0)
+#define p_MemDiff_LengthFive(r, s1, s2, length)  \
+do                                              \
+{                                               \
+  _p_MemDiff_Declare(r,s1,s2);                    \
+  _p_MemDiff_LengthFive(_r, _s1, _s2);           \
+}                                               \
+while (0)
+#define p_MemDiff_LengthSix(r, s1, s2, length)   \
+do                                              \
+{                                               \
+  _p_MemDiff_Declare(r,s1,s2);                    \
+  _p_MemDiff_LengthSix(_r, _s1, _s2);            \
+}                                               \
+while (0)
+#define p_MemDiff_LengthSeven(r, s1, s2, length) \
+do                                              \
+{                                               \
+  _p_MemDiff_Declare(r,s1,s2);                    \
+  _p_MemDiff_LengthSeven(_r, _s1, _s2);          \
+}                                               \
+while (0)
+#define p_MemDiff_LengthEight(r, s1, s2, length) \
+do                                              \
+{                                               \
+  _p_MemDiff_Declare(r,s1,s2);                    \
+  _p_MemDiff_LengthEight(_r, _s1, _s2);          \
+}                                               \
+while (0)
+
+#define p_MemDiff_LengthGeneral(r, s1, s2, length)   \
+do                                                  \
+{                                                   \
+  _p_MemDiff_Declare(r,s1,s2);                       \
+  const unsigned long _l = (unsigned long) length;       \
+  unsigned long _i = 0;                             \
+                                                    \
+  do                                                \
+  {                                                 \
+    _r[_i] = _s1[_i] - _s2[_i];                     \
+    _i++;                                           \
+  }                                                 \
+  while (_i != _l);                                 \
+}                                                   \
+while (0)
+
+
+/***************************************************************
+ *
+ * MemSub
+ *
+ ***************************************************************/
+
+#define _p_MemSub(i, r, s) r[i] -= s[i]
+
+#define _p_MemSub_LengthOne(r, s) _p_MemSub(0, r, s)
+#define _p_MemSub_LengthTwo(r, s) do{_p_MemSub_LengthOne(r, s); _p_MemSub(1, r, s);} while(0)
+#define _p_MemSub_LengthThree(r, s) do{_p_MemSub_LengthTwo(r, s); _p_MemSub(2, r, s);} while(0)
+#define _p_MemSub_LengthFour(r, s) do{_p_MemSub_LengthThree(r, s); _p_MemSub(3, r, s);} while(0)
+#define _p_MemSub_LengthFive(r, s) do{_p_MemSub_LengthFour(r, s); _p_MemSub(4, r, s);} while(0)
+#define _p_MemSub_LengthSix(r, s) do{_p_MemSub_LengthFive(r, s); _p_MemSub(5, r, s);} while(0)
+#define _p_MemSub_LengthSeven(r, s) do{_p_MemSub_LengthSix(r, s); _p_MemSub(6, r, s);} while(0)
+#define _p_MemSub_LengthEight(r, s) do{_p_MemSub_LengthSeven(r, s); _p_MemSub(7, r, s);} while(0)
+
+#define _p_MemSub_Declare(r, s)                \
+  const unsigned long* _s = ((unsigned long*) s); \
+  unsigned long* _r = ((unsigned long*) r)
+
+#define p_MemSub_LengthOne(r, s, length) _p_MemSub_LengthOne(r, s)
+#define p_MemSub_LengthTwo(r, s, length)   \
+do                                              \
+{                                               \
+  _p_MemSub_Declare(r,s);                    \
+  _p_MemSub_LengthTwo(_r, _s);            \
+}                                               \
+while (0)
+#define p_MemSub_LengthThree(r, s, length) \
+do                                              \
+{                                               \
+  _p_MemSub_Declare(r,s);                    \
+  _p_MemSub_LengthThree(_r, _s);          \
+}                                               \
+while (0)
+#define p_MemSub_LengthFour(r, s, length)  \
+do                                              \
+{                                               \
+  _p_MemSub_Declare(r,s);                    \
+  _p_MemSub_LengthFour(_r, _s);           \
+}                                               \
+while (0)
+#define p_MemSub_LengthFive(r, s, length)  \
+do                                              \
+{                                               \
+  _p_MemSub_Declare(r,s);                    \
+  _p_MemSub_LengthFive(_r, _s);           \
+}                                               \
+while (0)
+#define p_MemSub_LengthSix(r, s, length)   \
+do                                              \
+{                                               \
+  _p_MemSub_Declare(r,s);                    \
+  _p_MemSub_LengthSix(_r, _s);            \
+}                                               \
+while (0)
+#define p_MemSub_LengthSeven(r, s, length) \
+do                                              \
+{                                               \
+  _p_MemSub_Declare(r,s);                    \
+  _p_MemSub_LengthSeven(_r, _s);          \
+}                                               \
+while (0)
+#define p_MemSub_LengthEight(r, s, length) \
+do                                              \
+{                                               \
+  _p_MemSub_Declare(r,s);                    \
+  _p_MemSub_LengthEight(_r, _s);          \
+}                                               \
+while (0)
+
+#define p_MemSub_LengthGeneral(r, s, length)       \
+do                                                  \
+{                                                   \
+  _p_MemSub_Declare(r,s);                          \
+  const unsigned long _l = (unsigned long) length;  \
+  unsigned long _i = 0;                             \
+                                                    \
+  do                                                \
+  {                                                 \
+    _r[_i] -= _s[_i];                               \
+    _i++;                                           \
+  }                                                 \
+  while (_i != _l);                                 \
+}                                                   \
+while (0)
+
+#define _p_MemAddSub_Declare(r, s, t)                \
+  const unsigned long* _s = ((unsigned long*) s); \
+  const unsigned long* _t = ((unsigned long*) t); \
+  unsigned long* _r = ((unsigned long*) r)
+
+#define p_MemAddSub_LengthGeneral(r, s, t, length)  \
+do                                                  \
+{                                                   \
+  _p_MemAddSub_Declare(r,s, t);                     \
+  const unsigned long _l = (unsigned long) length;  \
+  unsigned long _i = 0;                             \
+                                                    \
+  do                                                \
+  {                                                 \
+    _r[_i] += _s[_i] - _t[_i];                      \
+    _i++;                                           \
+  }                                                 \
+  while (_i != _l);                                 \
+}                                                   \
+while (0)
+
+#endif /* P_MEM_ADD_H */
Index: kernel/p_MemCmp.h
===================================================================
--- kernel/p_MemCmp.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_MemCmp.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,949 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_MemCmp.h
+ *  Purpose: macros for memory comparisons
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_MemCmp.h,v 1.1.1.1 2003-10-06 12:15:59 Singular Exp $
+ *******************************************************************/
+#ifndef P_MEM_CMP_H
+#define P_MEM_CMP_H
+
+/***************************************************************
+ *
+ *  auxiallary macros
+ *
+ *******************************************************************/
+#define _p_MemCmp_Declare(s1, s2)                   \
+  const unsigned long* _s1 = ((unsigned long*) s1); \
+  const unsigned long* _s2 = ((unsigned long*) s2); \
+  register unsigned long _v1;                       \
+  register unsigned long _v2
+
+#define _p_MemCmp_Equal(i, s1, s2, actionE) \
+  do {  _v1=((unsigned long*)s1)[i]; _v2=((unsigned long*)s2)[i]; if (_v1==_v2) actionE; }while (0)
+#define _p_MemCmp_NotEqual(actionG, actionS)   \
+  do {if (_v1 > _v2) actionG; actionS;} while (0)
+
+#define _p_MemCmp_LengthOne_Equal(i, s1, s2, actionE) \
+  _p_MemCmp_Equal(i, s1, s2, actionE)
+#define _p_MemCmp_LengthTwo_Equal(i, s1, s2, actionE) \
+  _p_MemCmp_Equal(i, s1, s2, _p_MemCmp_Equal(i+1, s1, s2, actionE))
+#define _p_MemCmp_LengthThree_Equal(i, s1, s2, actionE) \
+  _p_MemCmp_LengthTwo_Equal(i, s1, s2, _p_MemCmp_Equal(i+2, s1, s2, actionE))
+#define _p_MemCmp_LengthFour_Equal(i, s1, s2, actionE) \
+  _p_MemCmp_LengthThree_Equal(i, s1, s2, _p_MemCmp_Equal(i+3, s1, s2, actionE))
+#define _p_MemCmp_LengthFive_Equal(i, s1, s2, actionE) \
+  _p_MemCmp_LengthFour_Equal(i, s1, s2, _p_MemCmp_Equal(i+4, s1, s2, actionE))
+#define _p_MemCmp_LengthSix_Equal(i, s1, s2, actionE) \
+  _p_MemCmp_LengthFive_Equal(i, s1, s2, _p_MemCmp_Equal(i+5, s1, s2, actionE))
+#define _p_MemCmp_LengthSeven_Equal(i, s1, s2, actionE) \
+  _p_MemCmp_LengthSix_Equal(i, s1, s2, _p_MemCmp_Equal(i+6, s1, s2, actionE))
+#define _p_MemCmp_LengthEight_Equal(i, s1, s2, actionE) \
+  _p_MemCmp_LengthSeven_Equal(i, s1, s2, _p_MemCmp_Equal(i+7, s1, s2, actionE))
+#define _p_MemCmp_LengthGeneral_Equal(i, s1, s2, length, actionE)   \
+do                                                                  \
+{                                                                   \
+                                                                    \
+  register unsigned long _i = (unsigned long) i;                    \
+  const unsigned long _l =                                          \
+         (unsigned long) length + (unsigned long)i ;                \
+                                                                    \
+  LengthGeneral_LoopTop:                                            \
+    _v1 = s1[_i];                                                   \
+    _v2 = s2[_i];                                                   \
+    if (_v1 == _v2)                                                 \
+    {                                                               \
+      _i++;                                                         \
+      if (_i == _l) actionE;                                        \
+      else  goto LengthGeneral_LoopTop;                             \
+    }                                                               \
+}                                                                   \
+while (0)
+
+/***************************************************************
+ *
+ *  Pomog
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+do                                                                          \
+{                                                                           \
+  _p_MemCmp_Declare(s1,s2);                                                 \
+  _p_MemCmp_LengthOne_Equal(0, _s1, _s2, actionE);                          \
+  _p_MemCmp_NotEqual(actionG, actionS);                                     \
+}                                                                           \
+while (0)
+#define p_MemCmp_LengthTwo_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+do                                                                          \
+{                                                                           \
+  _p_MemCmp_Declare(s1,s2);                                                 \
+  _p_MemCmp_LengthTwo_Equal(0, _s1, _s2, actionE);                 \
+  _p_MemCmp_NotEqual(actionG, actionS);                                      \
+}                                                                           \
+while (0)
+#define p_MemCmp_LengthThree_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Declare(s1,s2);                                                     \
+  _p_MemCmp_LengthThree_Equal(0, _s1, _s2, actionE);                   \
+  _p_MemCmp_NotEqual(actionG, actionS);                                      \
+}                                                                               \
+while (0)
+#define p_MemCmp_LengthFour_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Declare(s1,s2);                                                     \
+  _p_MemCmp_LengthFour_Equal(0, _s1, _s2, actionE);                    \
+  _p_MemCmp_NotEqual(actionG, actionS);                                      \
+}                                                                               \
+while (0)
+#define p_MemCmp_LengthFive_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Declare(s1,s2);                                                     \
+  _p_MemCmp_LengthFive_Equal(0, _s1, _s2, actionE);                    \
+  _p_MemCmp_NotEqual(actionG, actionS);                                      \
+}                                                                               \
+while (0)
+#define p_MemCmp_LengthSix_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+do                                                                          \
+{                                                                           \
+  _p_MemCmp_Declare(s1,s2);                                                 \
+  _p_MemCmp_LengthSix_Equal(0, _s1, _s2, actionE);                 \
+  _p_MemCmp_NotEqual(actionG, actionS);                                      \
+}                                                                           \
+while (0)
+#define p_MemCmp_LengthSeven_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Declare(s1,s2);                                                     \
+  _p_MemCmp_LengthSeven_Equal(0, _s1, _s2, actionE);                   \
+  _p_MemCmp_NotEqual(actionG, actionS);;                                      \
+}                                                                               \
+while (0)
+
+#define p_MemCmp_LengthEight_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Declare(s1,s2);                                                     \
+  _p_MemCmp_LengthEight_Equal(0, _s1, _s2, actionE);                   \
+  _p_MemCmp_NotEqual(actionG, actionS);                                      \
+}                                                                               \
+while (0)
+#define p_MemCmp_LengthGeneral_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Declare(s1,s2);                                                     \
+  _p_MemCmp_LengthGeneral_Equal(0, _s1, _s2, length, actionE);      \
+  _p_MemCmp_NotEqual(actionG, actionS);                                          \
+}                                                                               \
+while (0)
+
+/***************************************************************
+ *
+ *  Nomog
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthOne_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthTwo_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthTwo_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthThree_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthThree_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthFour_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthFive_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFive_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthSix_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthSix_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthSeven_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthEight_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthEight_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthGeneral_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+
+/***************************************************************
+ *
+ *  PomogZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthTwo_OrdPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthThree_OrdPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthTwo_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFour_OrdPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdPomog(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+/***************************************************************
+ *
+ *  NomogZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthTwo_OrdNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthOne_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthThree_OrdNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthTwo_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFour_OrdNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdNomog(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+/***************************************************************
+ *
+ *  NegPomog
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthTwo_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                      \
+                           _p_MemCmp_LengthOne_Equal(1, _s2, _s1,actionE),      \
+                           actionS, actionG)
+#define p_MemCmp_LengthThree_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_LengthTwo_Equal(1, _s2, _s1, actionE),              \
+                           actionS, actionG)
+#define p_MemCmp_LengthFour_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                      \
+                           _p_MemCmp_LengthThree_Equal(1, _s2, _s1, actionE),        \
+                           actionS, actionG)
+#define p_MemCmp_LengthFive_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                      \
+                           _p_MemCmp_LengthFour_Equal(1, _s2, _s1, actionE),         \
+                           actionS, actionG)
+#define p_MemCmp_LengthSix_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                      \
+                           _p_MemCmp_LengthFive_Equal(1, _s2, _s1, actionE),         \
+                           actionS, actionG)
+#define p_MemCmp_LengthSeven_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_LengthSix_Equal(1, _s2, _s1, actionE),              \
+                           actionS, actionG)
+#define p_MemCmp_LengthEight_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_LengthSeven_Equal(1, _s2, _s1, actionE),            \
+                           actionS, actionG)
+#define p_MemCmp_LengthGeneral_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)      \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                              \
+                           _p_MemCmp_LengthGeneral_Equal(1, _s2, _s1, (length) -1, actionE), \
+                           actionS, actionG)
+
+/***************************************************************
+ *
+ *  PomogNeg
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthTwo_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                      \
+                           _p_MemCmp_Equal(1, _s2, _s1, actionE),               \
+                           actionG, actionS)
+#define p_MemCmp_LengthThree_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthTwo_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_Equal(2, _s2, _s1, actionE),                   \
+                           actionG, actionS)
+#define p_MemCmp_LengthFour_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthThree_OrdPomog(s1, s2, length, ordsgn,                                    \
+                           _p_MemCmp_Equal(3, _s2, _s1, actionE),              \
+                           actionG, actionS)
+#define p_MemCmp_LengthFive_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthFour_OrdPomog(s1, s2, length, ordsgn,                                     \
+                           _p_MemCmp_Equal(4, _s2, _s1, actionE),               \
+                           actionG, actionS)
+#define p_MemCmp_LengthSix_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthFive_OrdPomog(s1, s2, length, ordsgn,                                     \
+                           _p_MemCmp_Equal(5, _s2, _s1, actionE),               \
+                           actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthSix_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_Equal(6, _s2, _s1, actionE),                   \
+                           actionG, actionS)
+#define p_MemCmp_LengthEight_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthSeven_OrdPomog(s1, s2, length, ordsgn,                                        \
+                           _p_MemCmp_Equal(7, _s2, _s1, actionE),                   \
+                           actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthGeneral_OrdPomog(s1, s2, (length-1), ordsgn,                                  \
+                           _p_MemCmp_Equal(_i, _s2, _s1, actionE),                  \
+                           actionG, actionS)
+
+/***************************************************************
+ *
+ *  PosNomog
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthThree_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthFour_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthFour_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthFive_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthFive_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthSix_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthSix_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthSeven_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthSeven_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthEight_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthEight_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthGeneral_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthGeneral_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionS, actionG)
+
+/***************************************************************
+ *
+ *  NomogPos
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthThree_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthFour_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthFour_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthFive_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthFive_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthSix_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthSix_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthSeven_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthSeven_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthEight_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthEight_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionS, actionG)
+#define p_MemCmp_LengthGeneral_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthGeneral_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionS, actionG)
+
+
+/***************************************************************
+ *
+ *  PomogNegZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthThree_OrdPomogNegZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthTwo_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFour_OrdPomogNegZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdPomogNegZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdPomogNegZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdPomogNegZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdPomogNegZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdPomogNeg(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdPomogNegZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdPomogNeg(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+/***************************************************************
+ *
+ *  NegPomogZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthThree_OrdNegPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthTwo_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFour_OrdNegPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdNegPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdNegPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdNegPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdNegPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdNegPomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdNegPomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdNegPomog(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+/***************************************************************
+ *
+ *  NomogPosZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthFour_OrdNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdNomogPos(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+/***************************************************************
+ *
+ *  PosNomogZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthFour_OrdPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdPosNomog(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+/***************************************************************
+ *
+ * PosPosNomog
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthThree_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)             \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s1, _s2,                                         \
+                                           _p_MemCmp_LengthOne_Equal(2, _s2, _s1, actionE)),    \
+                           actionG, actionS)
+#define p_MemCmp_LengthFour_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s1, _s2,                                         \
+                                           _p_MemCmp_LengthTwo_Equal(2, _s2, _s1, actionE)),    \
+                           actionG, actionS)
+#define p_MemCmp_LengthFive_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s1, _s2,                                         \
+                                           _p_MemCmp_LengthThree_Equal(2, _s2, _s1, actionE)),    \
+                           actionG, actionS)
+#define p_MemCmp_LengthSix_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s1, _s2,                                         \
+                                           _p_MemCmp_LengthFour_Equal(2, _s2, _s1, actionE)),    \
+                           actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s1, _s2,                                         \
+                                           _p_MemCmp_LengthFive_Equal(2, _s2, _s1, actionE)),    \
+                           actionG, actionS)
+#define p_MemCmp_LengthEight_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s1, _s2,                                         \
+                                           _p_MemCmp_LengthSix_Equal(2, _s2, _s1, actionE)),    \
+                           actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)          \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                     \
+                           _p_MemCmp_Equal(1, _s1, _s2,                                                   \
+                                           _p_MemCmp_LengthGeneral_Equal(2,_s2,_s1,(length-2), actionE)), \
+                           actionG, actionS)
+
+/***************************************************************
+ *
+ * NegPosNomog
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthThree_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)             \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s2, _s1,                                         \
+                                           _p_MemCmp_LengthOne_Equal(2, _s1, _s2, actionE)),    \
+                           actionS, actionG)
+#define p_MemCmp_LengthFour_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)              \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s2, _s1,                                         \
+                                           _p_MemCmp_LengthTwo_Equal(2, _s1, _s2, actionE)),    \
+                           actionS, actionG)
+#define p_MemCmp_LengthFive_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)              \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s2, _s1,                                         \
+                                           _p_MemCmp_LengthThree_Equal(2, _s1, _s2, actionE)),  \
+                           actionS, actionG)
+#define p_MemCmp_LengthSix_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)               \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s2, _s1,                                         \
+                                           _p_MemCmp_LengthFour_Equal(2, _s1, _s2, actionE)),   \
+                           actionS, actionG)
+#define p_MemCmp_LengthSeven_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)             \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s2, _s1,                                         \
+                                           _p_MemCmp_LengthFive_Equal(2, _s1, _s2, actionE)),   \
+                           actionS, actionG)
+#define p_MemCmp_LengthEight_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)             \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_Equal(1, _s2, _s1,                                         \
+                                           _p_MemCmp_LengthSix_Equal(2, _s1, _s2, actionE)),    \
+                           actionS, actionG)
+#define p_MemCmp_LengthGeneral_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)               \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                          \
+                           _p_MemCmp_Equal(1, _s2, _s1,                                             \
+                                           _p_MemCmp_LengthGeneral_Equal(2, _s1,_s2,                \
+                                                                         (length-2) , actionE)),    \
+                           actionS, actionG)
+
+/***************************************************************
+ *
+ * PosNomogPos
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthThree_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)             \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                      \
+                           _p_MemCmp_LengthOne_Equal(1, _s2, _s1,                               \
+                                           _p_MemCmp_LengthOne_Equal(2, _s1, _s2, actionE)),    \
+                           actionG, actionS)
+#define p_MemCmp_LengthFour_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_LengthTwo_Equal(1, _s2, _s1,                  \
+                                           _p_MemCmp_Equal(3, _s1, _s2, actionE)),  \
+                           actionG, actionS)
+#define p_MemCmp_LengthFive_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_LengthThree_Equal(1, _s2, _s1,                 \
+                                           _p_MemCmp_Equal(4, _s1, _s2, actionE)),  \
+                           actionG, actionS)
+#define p_MemCmp_LengthSix_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_LengthFour_Equal(1, _s2, _s1,                  \
+                                           _p_MemCmp_Equal(5, _s1, _s2, actionE)),  \
+                           actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_LengthFive_Equal(1, _s2, _s1,                  \
+                                           _p_MemCmp_Equal(6, _s1, _s2, actionE)),  \
+                           actionG, actionS)
+#define p_MemCmp_LengthEight_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                          \
+                           _p_MemCmp_LengthSix_Equal(1, _s2, _s1,                   \
+                                           _p_MemCmp_Equal(7, _s1, _s2, actionE)),  \
+                           actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)       \
+  p_MemCmp_LengthOne_OrdPomog(s1, s2, length, ordsgn,                                                  \
+                           _p_MemCmp_LengthGeneral_Equal(1, _s2, _s1, (length - 2),         \
+                                                   _p_MemCmp_Equal(_i, _s1, _s2, actionE)), \
+                           actionG, actionS)
+
+
+/***************************************************************
+ *
+ *  PosPosNomogZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthFour_OrdPosPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdPosPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdPosPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdPosPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdPosPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdPosPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdPosPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdPosPosNomog(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+/***************************************************************
+ *
+ *  PosNomogPosZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthFour_OrdPosNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdPosNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdPosNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdPosNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdPosNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdPosNomogPos(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdPosNomogPosZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdPosNomogPos(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+/***************************************************************
+ *
+ *  NegPosNomogZero
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthFour_OrdNegPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthThree_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthFive_OrdNegPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+  p_MemCmp_LengthFour_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSix_OrdNegPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)     \
+  p_MemCmp_LengthFive_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthSeven_OrdNegPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSix_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthEight_OrdNegPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+  p_MemCmp_LengthSeven_OrdNegPosNomog(s1, s2, length, ordsgn, actionE, actionG, actionS)
+#define p_MemCmp_LengthGeneral_OrdNegPosNomogZero(s1, s2, length, ordsgn, actionE, actionG, actionS) \
+  p_MemCmp_LengthGeneral_OrdNegPosNomog(s1, s2, (length) -1, ordsgn, actionE, actionG, actionS)
+
+
+/***************************************************************
+ *
+ *  OrdGeneral
+ *
+ *******************************************************************/
+#define _p_MemCmp_OrdGeneral_Declare(s1, s2)    \
+  const unsigned long* _s1 = ((unsigned long*) s1);     \
+  const unsigned long* _s2 = ((unsigned long*) s2);     \
+  register unsigned long _v1;                           \
+  register unsigned long _v2;                           \
+  register unsigned long _i
+
+#define _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS) \
+do                                                              \
+{                                                               \
+  const long* _ordsgn = (long*) ordsgn;                        \
+  if (_v1 > _v2)                                                \
+  {                                                             \
+    if (_ordsgn[_i] == 1) actionG;                              \
+    actionS;                                                    \
+  }                                                             \
+  if (_ordsgn[_i] == 1) actionS;                                \
+  actionG;                                                      \
+}                                                               \
+while (0)
+
+#define _p_MemCmp_OrdGeneral(i, actionE)         \
+do                                              \
+{                                               \
+  _i = i;                                       \
+  _v1 = _s1[i];                                 \
+  _v2 = _s2[i];                                 \
+  if (_v1 == _v2) actionE;                      \
+}                                               \
+while(0)
+
+#define _p_MemCmp_LengthTwo_OrdGeneral(actionE)          \
+  _p_MemCmp_OrdGeneral(0, _p_MemCmp_OrdGeneral(1, actionE))
+
+#define _p_MemCmp_LengthThree_OrdGeneral(actionE)          \
+  _p_MemCmp_LengthTwo_OrdGeneral(_p_MemCmp_OrdGeneral(2, actionE))
+
+#define _p_MemCmp_LengthFour_OrdGeneral(actionE)          \
+  _p_MemCmp_LengthThree_OrdGeneral(_p_MemCmp_OrdGeneral(3, actionE))
+
+#define _p_MemCmp_LengthFive_OrdGeneral(actionE)          \
+  _p_MemCmp_LengthFour_OrdGeneral(_p_MemCmp_OrdGeneral(4, actionE))
+
+#define _p_MemCmp_LengthSix_OrdGeneral(actionE)          \
+  _p_MemCmp_LengthFive_OrdGeneral(_p_MemCmp_OrdGeneral(5, actionE))
+
+#define _p_MemCmp_LengthSeven_OrdGeneral(actionE)          \
+  _p_MemCmp_LengthSix_OrdGeneral(_p_MemCmp_OrdGeneral(6, actionE))
+
+#define _p_MemCmp_LengthEight_OrdGeneral(actionE)          \
+  _p_MemCmp_LengthSeven_OrdGeneral(_p_MemCmp_OrdGeneral(7, actionE))
+
+#define p_MemCmp_LengthOne_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+do                                                                                          \
+{                                                                                           \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                     \
+  _p_MemCmp_OrdGeneral(0, actionE);                                                         \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                  \
+}                                                                                           \
+while (0)
+
+#define p_MemCmp_LengthTwo_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+do                                                                                          \
+{                                                                                           \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                     \
+  _p_MemCmp_LengthTwo_OrdGeneral(actionE);                                               \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                  \
+}                                                                                           \
+while (0)
+
+#define p_MemCmp_LengthThree_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+do                                                                                          \
+{                                                                                           \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                     \
+  _p_MemCmp_LengthThree_OrdGeneral(actionE);                                             \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                  \
+}                                                                                           \
+while (0)
+
+#define p_MemCmp_LengthFour_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+do                                                                                          \
+{                                                                                           \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                     \
+  _p_MemCmp_LengthFour_OrdGeneral(actionE);                                              \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                  \
+}                                                                                           \
+while (0)
+
+#define p_MemCmp_LengthFive_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+do                                                                                          \
+{                                                                                           \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                     \
+  _p_MemCmp_LengthFive_OrdGeneral(actionE);                                              \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                  \
+}                                                                                           \
+while (0)
+
+#define p_MemCmp_LengthSix_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+do                                                                                          \
+{                                                                                           \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                     \
+  _p_MemCmp_LengthSix_OrdGeneral(actionE);                                               \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                  \
+}                                                                                           \
+while (0)
+
+#define p_MemCmp_LengthSeven_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+do                                                                                          \
+{                                                                                           \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                     \
+  _p_MemCmp_LengthSeven_OrdGeneral(actionE);                                             \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                  \
+}                                                                                           \
+while (0)
+
+#define p_MemCmp_LengthEight_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)  \
+do                                                                                          \
+{                                                                                           \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                     \
+  _p_MemCmp_LengthEight_OrdGeneral(actionE);                                                \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                  \
+}                                                                                           \
+while (0)
+
+/***************************************************************
+ *
+ *  Last but not least LengthGeneral_OrdGeneral
+ *
+ *******************************************************************/
+#define p_MemCmp_LengthGeneral_OrdGeneral(s1, s2, length, ordsgn, actionE, actionG, actionS)    \
+do                                                                                              \
+{                                                                                               \
+  _p_MemCmp_OrdGeneral_Declare(s1, s2);                                                         \
+  const unsigned long _l = (unsigned long) length;                                              \
+                                                                                                \
+  _i=0;                                                                                         \
+                                                                                                \
+  LengthGeneral_OrdGeneral_LoopTop:                                                             \
+  _v1 = _s1[_i];                                                                                \
+  _v2 = _s2[_i];                                                                                \
+  if (_v1 == _v2)                                                                               \
+  {                                                                                             \
+    _i++;                                                                                       \
+    if (_i == _l) actionE;                                                                      \
+    goto LengthGeneral_OrdGeneral_LoopTop;                                                      \
+  }                                                                                             \
+                                                                                                \
+  _p_MemCmp_OrdGeneral_NotEqual(ordsgn, actionG, actionS);                                      \
+}                                                                                               \
+while (0)
+
+// or, in other (less efficient) words
+#define p_MemCmp_LengthGeneral_OrdGeneral2(s1, s2, length, ordsgn, actionE, actionG, actionS)   \
+do                                                                                              \
+{                                                                                               \
+  int _i;                                                                                       \
+                                                                                                \
+  for (_i=0; _i<length;_i++)                                                                    \
+  {                                                                                             \
+    if (s1[_i] != s2[_i])                                                                       \
+    {                                                                                           \
+      if (s1[_i] > s2[_i])                                                                      \
+      {                                                                                         \
+        if (ordsgn[_i] == 1)                                                                    \
+          actionG;                                                                              \
+        actionS;                                                                                \
+      }                                                                                         \
+      if (ordsgn[_i] == 1)                                                                      \
+        actionS;                                                                                \
+      actionG;                                                                                  \
+    }                                                                                           \
+  }                                                                                             \
+  actionE;                                                                                      \
+}                                                                                               \
+while (0)
+
+/***************************************************************
+ *
+ *  Bitmask
+ *
+ *******************************************************************/
+#define _p_MemCmp_Bitmask_Declare(s1, s2, bitmask)  \
+  const unsigned long* _s1 = ((unsigned long*) s1); \
+  const unsigned long* _s2 = ((unsigned long*) s2); \
+  register const unsigned long _bitmask = bitmask;  \
+  register unsigned long _v1;                       \
+  register unsigned long _v2;                       \
+  register unsigned long _i                         \
+
+
+#define p_MemCmp_Bitmask_LengthGeneral(s1, s2, bitmask, length, actionG, actionS)   \
+do                                                                                  \
+{                                                                                   \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                             \
+  const unsigned long _l = (unsigned long) length;                                  \
+                                                                                    \
+  _i=0;                                                                             \
+                                                                                    \
+  while (_i < _l)                                                                   \
+  {                                                                                 \
+    _v1 = _s1[_i];                                                                  \
+    _v2 = _s2[_i];                                                                  \
+                                                                                    \
+    if ((_v1 > _v2) ||                                                              \
+        (((_v1 & _bitmask) ^ (_v2 & _bitmask)) != ((_v2 - _v1) & _bitmask)))           \
+      actionS;                                                                      \
+    _i++;                                                                           \
+  }                                                                                 \
+  actionG;                                                                          \
+}                                                                                   \
+while (0)
+
+
+#define _p_MemCmp_Bitmask(i, actionS)                                       \
+do                                                                          \
+{                                                                           \
+  _i = i;                                                                   \
+  _v1 = _s1[i];                                                             \
+  _v2 = _s2[i];                                                             \
+  if ((_v1 > _v2) ||                                                        \
+      (((_v1 & _bitmask) ^ (_v2 & _bitmask)) != ((_v2 - _v1) & _bitmask)))     \
+    actionS;                                                               \
+}                                                                           \
+while (0)
+
+#define _p_MemCmp_Bitmask_LengthTwo(actionS)    \
+  do                                            \
+{                                               \
+  _p_MemCmp_Bitmask(0, actionS);                \
+  _p_MemCmp_Bitmask(1, actionS);                \
+}                                               \
+while (0)
+
+#define _p_MemCmp_Bitmask_LengthThree(actionS)  \
+  do                                            \
+{                                               \
+  _p_MemCmp_Bitmask_LengthTwo(actionS);         \
+  _p_MemCmp_Bitmask(2, actionS);                \
+}                                               \
+while (0)
+
+#define _p_MemCmp_Bitmask_LengthFour(actionS)   \
+  do                                            \
+{                                               \
+  _p_MemCmp_Bitmask_LengthThree(actionS);    \
+  _p_MemCmp_Bitmask(3, actionS);                \
+}                                               \
+while (0)
+
+
+#define _p_MemCmp_Bitmask_LengthFive(actionS)   \
+  do                                            \
+{                                               \
+  _p_MemCmp_Bitmask_LengthFour(actionS);     \
+  _p_MemCmp_Bitmask(4, actionS);                \
+}                                               \
+while (0)
+
+
+#define _p_MemCmp_Bitmask_LengthSix(actionS)    \
+  do                                            \
+{                                               \
+  _p_MemCmp_Bitmask_LengthFive(actionS);     \
+  _p_MemCmp_Bitmask(5, actionS);                \
+}                                               \
+while (0)
+
+#define _p_MemCmp_Bitmask_LengthSeven(actionS)  \
+  do                                            \
+{                                               \
+  _p_MemCmp_Bitmask_LengthSix(actionS);      \
+  _p_MemCmp_Bitmask(6, actionS);                \
+}                                               \
+while (0)
+
+#define _p_MemCmp_Bitmask_LengthEight(actionS)  \
+do                                              \
+{                                               \
+  _p_MemCmp_Bitmask_LengthSeven(actionS);    \
+  _p_MemCmp_Bitmask(7, actionS);                \
+}                                               \
+while (0)
+
+#define p_MemCmp_Bitmask_LengthZero(s1, s2, bitmask, length, actionG, actionS) actionG
+
+#define p_MemCmp_Bitmask_LengthOne(s1, s2, bitmask, length, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                         \
+  _p_MemCmp_Bitmask(0, actionS);                                                \
+  actionG;                                                                      \
+}                                                                               \
+while (0)
+
+#define p_MemCmp_Bitmask_LengthTwo(s1, s2, bitmask, length, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                         \
+  _p_MemCmp_Bitmask_LengthTwo(actionS);                                         \
+  actionG;                                                                      \
+}                                                                               \
+while (0)
+
+#define p_MemCmp_Bitmask_LengthThree(s1, s2, bitmask, length, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                         \
+  _p_MemCmp_Bitmask_LengthThree(actionS);                                         \
+  actionG;                                                                      \
+}                                                                               \
+while (0)
+
+#define p_MemCmp_Bitmask_LengthFour(s1, s2, bitmask, length, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                         \
+  _p_MemCmp_Bitmask_LengthFour(actionS);                                         \
+  actionG;                                                                      \
+}                                                                               \
+while (0)
+
+#define p_MemCmp_Bitmask_LengthFive(s1, s2, bitmask, length, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                         \
+  _p_MemCmp_Bitmask_LengthFive(actionS);                                         \
+  actionG;                                                                      \
+}                                                                               \
+while (0)
+
+#define p_MemCmp_Bitmask_LengthSix(s1, s2, bitmask, length, actionG, actionS)   \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                         \
+  _p_MemCmp_Bitmask_LengthSix(actionS);                                         \
+  actionG;                                                                      \
+}                                                                               \
+while (0)
+
+#define p_MemCmp_Bitmask_LengthSeven(s1, s2, bitmask, length, actionG, actionS) \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                         \
+  _p_MemCmp_Bitmask_LengthSeven(actionS);                                       \
+  actionG;                                                                      \
+}                                                                               \
+while (0)
+
+#define p_MemCmp_Bitmask_LengthEigth(s1, s2, bitmask, length, actionG, actionS) \
+do                                                                              \
+{                                                                               \
+  _p_MemCmp_Bitmask_Declare(s1, s2, bitmask);                                         \
+  _p_MemCmp_Bitmask_LengthEigth(actionS);                                       \
+  actionG;                                                                      \
+}                                                                               \
+while (0)
+
+
+#endif // P_MEM_CMP
Index: kernel/p_MemCopy.h
===================================================================
--- kernel/p_MemCopy.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_MemCopy.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,96 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_MemCopy.h
+ *  Purpose: macros for memory addition
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_MemCopy.h,v 1.1.1.1 2003-10-06 12:15:59 Singular Exp $
+ *******************************************************************/
+#ifndef P_MEM_COPY_H
+#define P_MEM_COPY_H
+
+#define _p_MemCopy(i, d, s) d[i] = s[i]
+
+#define _p_MemCopy_LengthOne(d, s) _p_MemCopy(0, d, s)
+#define _p_MemCopy_LengthTwo(d, s) do{_p_MemCopy_LengthOne(d, s); _p_MemCopy(1, d, s);} while(0)
+#define _p_MemCopy_LengthThree(d, s) do{_p_MemCopy_LengthTwo(d, s); _p_MemCopy(2, d, s);} while(0)
+#define _p_MemCopy_LengthFour(d, s) do{_p_MemCopy_LengthThree(d, s); _p_MemCopy(3, d, s);} while(0)
+#define _p_MemCopy_LengthFive(d, s) do{_p_MemCopy_LengthFour(d, s); _p_MemCopy(4, d, s);} while(0)
+#define _p_MemCopy_LengthSix(d, s) do{_p_MemCopy_LengthFive(d, s); _p_MemCopy(5, d, s);} while(0)
+#define _p_MemCopy_LengthSeven(d, s) do{_p_MemCopy_LengthSix(d, s); _p_MemCopy(6, d, s);} while(0)
+#define _p_MemCopy_LengthEight(d, s) do{_p_MemCopy_LengthSeven(d, s); _p_MemCopy(7, d, s);} while(0)
+
+#define _p_MemCopy_Declare(d, s)                \
+  unsigned long* _d = ((unsigned long*) d); \
+  const unsigned long* _s = ((unsigned long*) s)
+
+#define p_MemCopy_LengthOne(d, s, length) _p_MemCopy_LengthOne(d, s)
+#define p_MemCopy_LengthTwo(d, s, length)   \
+do                                              \
+{                                               \
+  _p_MemCopy_Declare(d,s);                    \
+  _p_MemCopy_LengthTwo(_d, _s);            \
+}                                               \
+while (0)
+#define p_MemCopy_LengthThree(d, s, length) \
+do                                              \
+{                                               \
+  _p_MemCopy_Declare(d,s);                    \
+  _p_MemCopy_LengthThree(_d, _s);          \
+}                                               \
+while (0)
+#define p_MemCopy_LengthFour(d, s, length)  \
+do                                              \
+{                                               \
+  _p_MemCopy_Declare(d,s);                    \
+  _p_MemCopy_LengthFour(_d, _s);           \
+}                                               \
+while (0)
+#define p_MemCopy_LengthFive(d, s, length)  \
+do                                              \
+{                                               \
+  _p_MemCopy_Declare(d,s);                    \
+  _p_MemCopy_LengthFive(_d, _s);           \
+}                                               \
+while (0)
+#define p_MemCopy_LengthSix(d, s, length)   \
+do                                              \
+{                                               \
+  _p_MemCopy_Declare(d,s);                    \
+  _p_MemCopy_LengthSix(_d, _s);            \
+}                                               \
+while (0)
+#define p_MemCopy_LengthSeven(d, s, length) \
+do                                              \
+{                                               \
+  _p_MemCopy_Declare(d,s);                    \
+  _p_MemCopy_LengthSeven(_d, _s);          \
+}                                               \
+while (0)
+#define p_MemCopy_LengthEight(d, s, length) \
+do                                              \
+{                                               \
+  _p_MemCopy_Declare(d,s);                    \
+  _p_MemCopy_LengthEight(_d, _s);          \
+}                                               \
+while (0)
+
+#define p_MemCopy_LengthGeneral(d, s, length)   \
+do                                              \
+{                                               \
+  _p_MemCopy_Declare(d,s);                      \
+  const unsigned long _l = (unsigned long) length;   \
+  unsigned long _i = 0;                         \
+                                                \
+  do                                            \
+  {                                             \
+    _d[_i] = _s[_i];                            \
+    _i++;                                       \
+  }                                             \
+  while (_i != _l);                             \
+}                                               \
+while (0)
+
+#endif // P_MEM_COPY_H
Index: kernel/p_Merge_q__T.cc
===================================================================
--- kernel/p_Merge_q__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Merge_q__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,60 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Merge_q__Template.cc
+ *  Purpose: template for p_Add_q
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_Merge_q__T.cc,v 1.1.1.1 2003-10-06 12:15:59 Singular Exp $
+ *******************************************************************/
+
+/***************************************************************
+ *
+ * Returns:  p merged with q
+ * Destroys: p, q
+ *
+ ***************************************************************/
+LINKAGE poly p_Merge_q(poly p, poly q, const ring r)
+{
+  assume(p != NULL && q != NULL);
+  p_Test(p, r);
+  p_Test(q, r);
+#if PDEBUG > 0
+  int l = pLength(p) + pLength(q);
+#endif
+
+  spolyrec rp;
+  poly a = &rp;
+  DECLARE_LENGTH(const unsigned long length = r->CmpL_Size);
+  DECLARE_ORDSGN(const long* ordsgn = r->ordsgn);
+
+  Top:     // compare p and q w.r.t. monomial ordering
+  p_MemCmp(p->exp, q->exp, length, ordsgn, goto Equal, goto Greater , goto Smaller);
+
+  Equal:
+  // should never get here
+  dReportError("Equal monomials in p_Merge_q");
+  return NULL;
+
+  Greater:
+  a = pNext(a) = p;
+  pIter(p);
+  if (p==NULL) { pNext(a) = q; goto Finish;}
+  goto Top;
+
+  Smaller:
+  a = pNext(a) = q;
+  pIter(q);
+  if (q==NULL) { pNext(a) = p; goto Finish;}
+  goto Top;
+
+  Finish:
+
+  p_Test(pNext(&rp), r);
+#if PDEBUG > 0
+  pAssume1(l - pLength(pNext(&rp)) == 0);
+#endif
+  return pNext(&rp);
+}
+
Index: kernel/p_Minus_mm_Mult_qq__T.cc
===================================================================
--- kernel/p_Minus_mm_Mult_qq__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Minus_mm_Mult_qq__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,137 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Minus_mm_Mult_qq__Template.cc
+ *  Purpose: template for p_Minus_m_Mult_q
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_Minus_mm_Mult_qq__T.cc,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+
+/***************************************************************
+ *
+ * Returns:  p - m*q
+ *           Shorter, where Shorter == Length(p) + Length(q) - Length(p - m*q);
+ * Destroys: p
+ * Const:    m, q
+ *
+ ***************************************************************/
+LINKAGE poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, int& Shorter, const poly spNoether, const ring r, poly &last)
+{
+  p_Test(p, r);
+  p_Test(q, r);
+  p_LmTest(m, r);
+
+#if PDEBUG > 0
+  int l_debug = pLength(p) + pLength(q);
+#endif
+
+  Shorter = 0;
+  // we are done if q == NULL || m == NULL
+  if (q == NULL || m == NULL) return p;
+
+  spolyrec rp;
+  poly a = &rp,                    // collects the result
+    qm = NULL,                     // stores q*m
+    c;                             // used for temporary storage
+
+
+  number tm   = pGetCoeff(m),           // coefficient of m
+    tneg = n_Neg(n_Copy(tm, r), r),    // - (coefficient of m)
+    tb,                            // used for tm*coeff(a1)
+    tc;                            // used as intermediate number
+
+
+  int shorter = 0;
+  DECLARE_LENGTH(const unsigned long length = r->ExpL_Size);
+  DECLARE_ORDSGN(const long* ordsgn = r->ordsgn);
+
+  const unsigned long* m_e = m->exp;
+  omBin bin = r->PolyBin;
+
+  if (p == NULL) goto Finish;           // return tneg*q if (p == NULL)
+
+  pAssume(p_GetComp(q, r) == 0 || p_GetComp(m, r) == 0);
+
+  AllocTop:
+  p_AllocBin(qm, bin, r);
+  SumTop:
+  p_MemSum(qm->exp, q->exp, m_e, length);
+  p_MemAddAdjust(qm, r);
+
+  CmpTop:
+  // compare qm = m*q and p w.r.t. monomial ordering
+  p_MemCmp(qm->exp, p->exp, length, ordsgn, goto Equal, goto Greater, goto Smaller );
+
+  Equal:   // qm equals p
+  tb = n_Mult(pGetCoeff(q), tm, r);
+  tc = pGetCoeff(p);
+  if (!n_Equal(tc, tb, r))
+  {
+    shorter++;
+    tc = n_Sub(tc, tb, r);
+    n_Delete(&(pGetCoeff(p)), r);
+    pSetCoeff0(p,tc); // adjust coeff of p
+    a = pNext(a) = p; // append p to result and advance p
+    pIter(p);
+  }
+  else
+  { // coeffs are equal, so their difference is 0:
+    shorter += 2;
+    n_Delete(&tc, r);
+    p = p_LmFreeAndNext(p, r);
+  }
+  n_Delete(&tb, r);
+  pIter(q);
+  if (q == NULL || p == NULL) goto Finish; // are we done ?
+  // no, so update qm
+  goto SumTop;
+
+
+  Greater:
+  pSetCoeff0(qm, n_Mult(pGetCoeff(q), tneg, r));
+  a = pNext(a) = qm;       // append qm to result and advance q
+  pIter(q);
+  if (q == NULL) // are we done?
+  {
+    qm = NULL;
+    goto Finish;
+  }
+  // construct new qm
+  goto AllocTop;
+
+  Smaller:
+  a = pNext(a) = p;// append p to result and advance p
+  pIter(p);
+  if (p == NULL) goto Finish;
+  goto CmpTop;
+
+
+  Finish: // q or p is NULL: Clean-up time
+  if (q == NULL) // append rest of p to result
+  {
+    pNext(a) = p;
+    if (p == NULL) last = a;
+  }
+  else  // append (- m*q) to result
+  {
+    pSetCoeff0(m, tneg);
+    last = a;
+    if (spNoether != NULL)
+    {
+      int ll = 0;
+      pNext(a) = r->p_Procs->pp_Mult_mm_Noether(q, m, spNoether, ll, r, last);
+      shorter += ll;
+    }
+    else
+      pNext(a) = r->p_Procs->pp_Mult_mm(q, m, r, last);
+    pSetCoeff0(m, tm);
+  }
+
+  n_Delete(&tneg, r);
+  if (qm != NULL) p_FreeBinAddr(qm, r);
+  Shorter = shorter;
+  p_Test(pNext(&rp), r);
+  return pNext(&rp);
+}
Index: kernel/p_Mult_mm__T.cc
===================================================================
--- kernel/p_Mult_mm__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Mult_mm__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,45 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Mult_mm__Template.cc
+ *  Purpose: template for p_Mult_n
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_Mult_mm__T.cc,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+
+/***************************************************************
+ *
+ *   Returns:  p*m
+ *   Const:    m
+ *   Destroys: p
+ *
+ ***************************************************************/
+LINKAGE poly p_Mult_mm(poly p, const poly m, const ring ri)
+{
+  p_Test(p, ri);
+  p_LmTest(m, ri);
+  if (p == NULL) return NULL;
+  pAssume(m != NULL);
+  poly q = p;
+  number ln = pGetCoeff(m);
+  number pn;
+  DECLARE_LENGTH(const unsigned long length = ri->ExpL_Size);
+  const unsigned long* m_e = m->exp;
+  pAssume(!n_IsZero(ln,ri));
+
+  while (p != NULL)
+  {
+    pn = pGetCoeff(p);
+    pSetCoeff0(p, n_Mult(ln, pn, ri));
+    n_Delete(&pn, ri);
+    p_MemAdd(p->exp, m_e, length);
+    p_MemAddAdjust(p, ri);
+    p = pNext(p);
+  }
+  p_Test(q, ri);
+  return q;
+}
+
+
Index: kernel/p_Mult_nn__T.cc
===================================================================
--- kernel/p_Mult_nn__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Mult_nn__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,36 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Mult_n__Template.cc
+ *  Purpose: template for p_Mult_n
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_Mult_nn__T.cc,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+
+/***************************************************************
+ *
+ *   Returns:  p*n
+ *   Destroys: p
+ *   Const:    n
+ *
+ ***************************************************************/
+LINKAGE poly p_Mult_nn(poly p, const number n, const ring r)
+{
+  pAssume(!n_IsZero(n,r));
+  p_Test(p, r);
+
+  poly q = p;
+  while (p != NULL)
+  {
+    number nc = pGetCoeff(p);
+    pSetCoeff0(p, n_Mult(n, nc, r));
+    n_Delete(&nc, r);
+    pIter(p);
+  }
+  p_Test(q, r);
+  return q;
+}
+
+
Index: kernel/p_Mult_q.cc
===================================================================
--- kernel/p_Mult_q.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Mult_q.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,257 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Mult_q.cc
+ *  Purpose: multiplication of polynomials
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_Mult_q.cc,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+#include "mod2.h"
+
+/***************************************************************
+ *
+ * Returns:  p * q,
+ * Destroys: if !copy then p, q
+ * Assumes: pLength(p) >= 2 pLength(q) >=2
+ ***************************************************************/
+#include "p_polys.h"
+#include "p_Procs.h"
+#include "p_Numbers.h"
+#include "kbuckets.h"
+
+#include "p_Mult_q.h"
+
+BOOLEAN pqLength(poly p, poly q, int &lp, int &lq, const int min)
+{
+  int l = 0;
+
+  do
+  {
+    if (p == NULL)
+    {
+      lp = l;
+      if (l < min)
+      {
+        if (q != NULL)
+          lq = l+1;
+        else
+          lq = l;
+        return FALSE;
+      }
+      lq = l + pLength(q);
+      return TRUE;
+    }
+    pIter(p);
+    if (q == NULL)
+    {
+      lq = l;
+      if (l < min)
+      {
+        lp = l+1;
+        return FALSE;
+      }
+      lp = l + 1 + pLength(p);
+      return TRUE;
+    }
+    pIter(q);
+    l++;
+  }
+  while (1);
+}
+
+
+static poly _p_Mult_q_Bucket(poly p, const int lp,
+                             poly q, const int lq,
+                             const int copy, const ring r)
+{
+  assume(p != NULL && pNext(p) != NULL && q != NULL && pNext(q) != NULL);
+  pAssume1(! pHaveCommonMonoms(p, q));
+  assume(lp >= 1 && lq >= 1);
+  p_Test(p, r);
+  p_Test(q, r);
+
+  poly res = pp_Mult_mm(p,q,r);     // holds initially q1*p
+  poly qq = pNext(q);               // we iter of this
+  poly qn = pp_Mult_mm(qq, p,r);    // holds p1*qi
+  poly pp = pNext(p);               // used for Lm(qq)*pp
+  poly rr = res;                    // last monom which is surely not NULL
+  poly rn = pNext(res);             // pNext(rr)
+  number n, n1;
+
+  kBucket_pt bucket = kBucketCreate(r);
+
+  // initialize bucket
+  kBucketInit(bucket, pNext(rn), lp - 2);
+  pNext(rn) = NULL;
+
+  // now the main loop
+  Top:
+  if (rn == NULL) goto Smaller;
+  p_LmCmpAction(rn, qn, r, goto Equal, goto Greater, goto Smaller);
+
+  Greater:
+  // rn > qn, so iter
+  rr = rn;
+  pNext(rn) = kBucketExtractLm(bucket);
+  pIter(rn);
+  goto Top;
+
+  // rn < qn, append qn to rr, and compute next Lm(qq)*pp
+  Smaller:
+  pNext(rr) = qn;
+  rr = qn;
+  pIter(qn);
+  Work: // compute res + Lm(qq)*pp
+  if (rn == NULL)
+  {
+    pNext(rr) = pp_Mult_mm(pp, qq, r);
+    kBucketInit(bucket, pNext(pNext(rr)), lp - 2);
+    pNext(pNext(rr)) = NULL;
+  }
+  else
+  {
+    kBucketSetLm(bucket, rn);
+    kBucket_Plus_mm_Mult_pp(bucket, qq, pp, lp - 1);
+    pNext(rr) = kBucketExtractLm(bucket);
+  }
+
+  pIter(qq);
+  if (qq == NULL) goto Finish;
+  rn = pNext(rr);
+  goto Top;
+
+  Equal:
+  n1 = pGetCoeff(rn);
+  n = n_Add(n1, pGetCoeff(qn), r);
+  n_Delete(&n1, r);
+  if (n_IsZero(n, r))
+  {
+    n_Delete(&n, r);
+    p_LmFree(rn, r);
+  }
+  else
+  {
+    pSetCoeff0(rn, n);
+    rr = rn;
+  }
+  rn = kBucketExtractLm(bucket);
+  n_Delete(&pGetCoeff(qn),r);
+  qn = p_LmFreeAndNext(qn, r);
+  goto Work;
+
+  Finish:
+  assume(rr != NULL && pNext(rr) != NULL);
+  pNext(pNext(rr)) = kBucketClear(bucket);
+  kBucketDestroy(&bucket);
+
+  if (!copy)
+  {
+    p_Delete(&p, r);
+    p_Delete(&q, r);
+  }
+  p_Test(res, r);
+  return res;
+}
+
+
+static poly _p_Mult_q_Normal(poly p, poly q, const int copy, const ring r)
+{
+  assume(p != NULL && pNext(p) != NULL && q != NULL && pNext(q) != NULL);
+  pAssume1(! pHaveCommonMonoms(p, q));
+  p_Test(p, r);
+  p_Test(q, r);
+
+  poly res = pp_Mult_mm(p,q,r);     // holds initially q1*p
+  poly qq = pNext(q);               // we iter of this
+  poly qn = pp_Mult_mm(qq, p,r);    // holds p1*qi
+  poly pp = pNext(p);               // used for Lm(qq)*pp
+  poly rr = res;                    // last monom which is surely not NULL
+  poly rn = pNext(res);             // pNext(rr)
+  number n, n1;
+
+  // now the main loop
+  Top:
+  if (rn == NULL) goto Smaller;
+  p_LmCmpAction(rn, qn, r, goto Equal, goto Greater, goto Smaller);
+
+  Greater:
+  // rn > qn, so iter
+  rr = rn;
+  pIter(rn);
+  goto Top;
+
+  // rn < qn, append qn to rr, and compute next Lm(qq)*pp
+  Smaller:
+  pNext(rr) = qn;
+  rr = qn;
+  pIter(qn);
+  Work: // compute res + Lm(qq)*pp
+  if (rn == NULL)
+    pNext(rr) = pp_Mult_mm(pp, qq, r);
+  else
+  {
+    pNext(rr) = p_Plus_mm_Mult_qq(rn, qq, pp, r);
+  }
+
+  pIter(qq);
+  if (qq == NULL) goto Finish;
+  rn = pNext(rr);
+  goto Top;
+
+  Equal:
+  n1 = pGetCoeff(rn);
+  n = n_Add(n1, pGetCoeff(qn), r);
+  n_Delete(&n1, r);
+  if (n_IsZero(n, r))
+  {
+    n_Delete(&n, r);
+    rn = p_LmFreeAndNext(rn, r);
+  }
+  else
+  {
+    pSetCoeff0(rn, n);
+    rr = rn;
+    pIter(rn);
+  }
+  n_Delete(&pGetCoeff(qn),r);
+  qn = p_LmFreeAndNext(qn, r);
+  goto Work;
+
+  Finish:
+  if (!copy)
+  {
+    p_Delete(&p, r);
+    p_Delete(&q, r);
+  }
+  p_Test(res, r);
+  return res;
+}
+
+
+poly _p_Mult_q(poly p, poly q, const int copy, const ring r)
+{
+  int lp, lq, l;
+  poly pt;
+
+  pqLength(p, q, lp, lq, MIN_LENGTH_BUCKET);
+
+  if (lp < lq)
+  {
+    pt = p;
+    p =  q;
+    q = pt;
+    l = lp;
+    lp = lq;
+    lq = l;
+  }
+  if (lq < MIN_LENGTH_BUCKET || TEST_OPT_NOT_BUCKETS)
+    return _p_Mult_q_Normal(p, q, copy, r);
+  else
+  {
+    assume(lp == pLength(p));
+    assume(lq == pLength(q));
+    return _p_Mult_q_Bucket(p, lp, q, lq, copy, r);
+  }
+}
Index: kernel/p_Mult_q.h
===================================================================
--- kernel/p_Mult_q.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Mult_q.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,25 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Mult_q.h
+ *  Purpose: declaration of some auxillary routines for
+ *           p_Mult_q
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_Mult_q.h,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+#include "mod2.h"
+#include "structs.h"
+
+// Use buckets if min(pLength(p), pLength(q)) >= MIN_LENGTH_BUCKET
+// Not thoroughly tested what is best
+#define MIN_LENGTH_BUCKET 10
+
+//  return TRUE and lp == pLength(p), lq == pLength(q),
+//              if min(pLength(p), pLength(q)) >= min
+//         FALSE if min(pLength(p), pLength(q)) < min
+//              and lp >= lq if pLength(p) >= pLength(lq)
+//                  lp < lq  if pLength(p) < pLength(q)
+BOOLEAN pqLength(poly p, poly q, int &lp, int &lq, const int min);
+
Index: kernel/p_Neg__T.cc
===================================================================
--- kernel/p_Neg__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Neg__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,29 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Neg__Template.cc
+ *  Purpose: template for p_Neg
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_Neg__T.cc,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+
+/***************************************************************
+ *
+ *   Returns:  -p
+ *   Destroys: p
+ *
+ ***************************************************************/
+LINKAGE poly p_Neg(poly p, const ring r)
+{
+  poly q = p;
+  while (p != NULL)
+  {
+    pSetCoeff0(p, n_Neg(pGetCoeff(p), r));
+    pIter(p);
+  }
+  return q;
+}
+
+
Index: kernel/p_Numbers.h
===================================================================
--- kernel/p_Numbers.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Numbers.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,48 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Numbers.h
+ *  Purpose: macros/inline functions for number oerations
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_Numbers.h,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+#ifndef P_NUMBERS_H
+#define P_NUMBERS_H
+
+#include "numbers.h"
+#define n_Copy_FieldGeneral(n, r)           (r)->cf->cfCopy(n,r)
+#define n_Delete_FieldGeneral(n, r)         (r)->cf->cfDelete(n,r)
+#define n_Mult_FieldGeneral(n1, n2, r)      (r)->cf->nMult(n1, n2)
+#define n_Add_FieldGeneral(n1, n2, r)       (r)->cf->nAdd(n1, n2)
+#define n_IsZero_FieldGeneral(n, r)         (r)->cf->nIsZero(n)
+#define n_Equal_FieldGeneral(n1, n2, r)     (r)->cf->nEqual(n1, n2)
+#define n_Neg_FieldGeneral(n, r)            (r)->cf->nNeg(n)
+#define n_Sub_FieldGeneral(n1, n2, r)       (r)->cf->nSub(n1, n2)
+//#define n_InpMult_FieldGeneral(n1, n2, r)   (r)->cf->nInpMult(n1, n2, r)
+#define n_InpMult_FieldGeneral(n1, n2, r)   ndInpMult(n1, n2, r)
+
+#include "modulop.h"
+#define n_Copy_FieldZp(n, r)        n
+#define n_Delete_FieldZp(n, r)      ((void)0)
+#define n_Mult_FieldZp(n1, n2, r)   npMultM(n1,n2)
+#define n_Add_FieldZp(n1, n2, r)    npAddM(n1, n2)
+#define n_IsZero_FieldZp(n, r)      npIsZeroM(n)
+#define n_Equal_FieldZp(n1, n2, r)  npEqualM(n1, n2)
+#define n_Neg_FieldZp(n, r)         npNegM(n)
+#define n_Sub_FieldZp(n1, n2, r)    npSubM(n1, n2)
+#define n_InpMult_FieldZp(n1, n2, r) n1=npMultM(n1, n2)
+
+#define DO_LINLINE
+#include "longrat.cc"
+#define n_Copy_FieldQ(n, r)        nlCopy(n)
+#define n_Delete_FieldQ(n, r)      nlDelete(n,r)
+#define n_Mult_FieldQ(n1, n2, r)   nlMult(n1,n2)
+#define n_Add_FieldQ(n1, n2, r)    nlAdd(n1, n2)
+#define n_IsZero_FieldQ(n, r)      nlIsZero(n)
+#define n_Equal_FieldQ(n1, n2, r)  nlEqual(n1, n2)
+#define n_Neg_FieldQ(n, r)         nlNeg(n)
+#define n_Sub_FieldQ(n1, n2, r)    nlSub(n1, n2)
+#define n_InpMult_FieldQ(n1, n2, r) nlInpMult(n1, n2, r)
+#endif
Index: kernel/p_Procs.h
===================================================================
--- kernel/p_Procs.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Procs.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,71 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/***************************************************************
+ *  File:    pProcs.h
+ *  Purpose: declaration of primitive procs for polys
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_Procs.h,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+#ifndef P_PROCS_H
+#define P_PROCS_H
+#include "structs.h"
+
+/*------------- p_Proc stuff ----------------------*/
+typedef poly (*p_Copy_Proc_Ptr)(poly p, const ring r);
+typedef void (*p_Delete_Proc_Ptr)(poly *p, const ring r);
+typedef poly (*p_ShallowCopyDelete_Proc_Ptr)(poly p, const ring r, omBin_s* dest_bin);
+typedef poly (*p_Mult_nn_Proc_Ptr)(poly p, const number n, const ring r);
+typedef poly (*pp_Mult_nn_Proc_Ptr)(poly p, const number n, const ring r);
+typedef poly (*p_Mult_mm_Proc_Ptr)(poly p, const poly m, const ring r);
+typedef poly (*pp_Mult_mm_Proc_Ptr)(poly p, const poly m,
+                                    const ring r,
+                                    poly &last);
+typedef poly (*pp_Mult_mm_Noether_Proc_Ptr)(poly p, const poly m,
+                                            const poly spNoether, int &ll,
+                                            const ring r, poly &last);
+typedef poly (*p_Add_q_Proc_Ptr)(poly p, poly q, int & shorter, const ring r);
+typedef poly (*p_Minus_mm_Mult_qq_Proc_Ptr)(poly p, poly m, poly q,
+                                            int &shorter, const poly spNoether,
+                                            const ring r, poly &last);
+typedef poly (*p_Neg_Proc_Ptr)(poly p, const ring r);
+typedef poly (*pp_Mult_Coeff_mm_DivSelect_Proc_Ptr)(poly p, const poly m,
+                                                    int &shorter,const ring r);
+typedef poly (*pp_Mult_Coeff_mm_DivSelectMult_Proc_Ptr)
+  (poly p,const poly m, const poly a, const poly b, int &shorter,const ring r);
+
+typedef poly (*p_Merge_q_Proc_Ptr)(poly p, poly q, const ring r);
+typedef void (*p_kBucketSetLm_Proc_Ptr)(kBucket_pt bucket);
+
+typedef struct p_Procs_s
+{
+  p_Copy_Proc_Ptr                       p_Copy;
+  p_Delete_Proc_Ptr                     p_Delete;
+  p_ShallowCopyDelete_Proc_Ptr          p_ShallowCopyDelete;
+  p_Mult_nn_Proc_Ptr                    p_Mult_nn;
+  pp_Mult_nn_Proc_Ptr                   pp_Mult_nn;
+  pp_Mult_mm_Proc_Ptr                   pp_Mult_mm;
+  pp_Mult_mm_Noether_Proc_Ptr           pp_Mult_mm_Noether;
+  p_Mult_mm_Proc_Ptr                    p_Mult_mm;
+  p_Add_q_Proc_Ptr                      p_Add_q;
+  p_Minus_mm_Mult_qq_Proc_Ptr           p_Minus_mm_Mult_qq;
+  p_Neg_Proc_Ptr                        p_Neg;
+  pp_Mult_Coeff_mm_DivSelect_Proc_Ptr   pp_Mult_Coeff_mm_DivSelect;
+  pp_Mult_Coeff_mm_DivSelectMult_Proc_Ptr   pp_Mult_Coeff_mm_DivSelectMult;
+  p_Merge_q_Proc_Ptr                    p_Merge_q;
+  p_kBucketSetLm_Proc_Ptr               p_kBucketSetLm;
+} pProcs_s;
+
+
+void p_ProcsSet(ring r, p_Procs_s* p_Procs);
+#ifdef RDEBUG
+void p_Debug_GetSpecNames(const ring r, char* &field, char* &length,
+                          char* &ord);
+void p_Debug_GetProcNames(const ring r, p_Procs_s* p_Procs);
+#endif
+// if set, then dynamic p_procs are used, otherwise static
+extern BOOLEAN p_procs_dynamic;
+
+#endif /* ! P_PROCS_H */
Index: kernel/p_Procs_Dynamic.cc
===================================================================
--- kernel/p_Procs_Dynamic.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Procs_Dynamic.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,228 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Procs_Dynamic.cc
+ *  Purpose: source for dynamically loaded version of p_Procs
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *  Version: $Id: p_Procs_Dynamic.cc,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+#include "mod2.h"
+#include "structs.h"
+#include "p_polys.h"
+#include "ring.h"
+#include "p_Procs.h"
+#include "p_Numbers.h"
+#include "p_MemCmp.h"
+#include "p_MemAdd.h"
+#include "p_MemCopy.h"
+#include "kbuckets.h"
+#include "dError.h"
+
+BOOLEAN p_procs_dynamic = TRUE;
+
+#define WARN_MSG "Singular will work properly, but much slower."
+
+// need external linkage, so that dynl_sym works
+#undef LINKAGE
+#define LINKAGE extern "C"
+#define p_Procs_Kernel
+#include "p_Procs_Dynamic.inc"
+
+#include "p_Procs_Dynamic.h"
+// include general p_Proc stuff
+#include "p_Procs_Impl.h"
+#include "mod_raw.h"
+
+// define to bound for length of p_Proc name
+#define MAX_PROCNAME_LEN 200
+
+static void* p_procs_handle_FieldIndep = NULL;
+static void* p_procs_handle_FieldZp = NULL;
+static void* p_procs_handle_FieldQ = NULL;
+static void* p_procs_handle_FieldGeneral = NULL;
+
+static void* p_ProcInitHandle(void** handle, const char* module)
+{
+  if (*handle == NULL)
+  {
+    char name[25];
+    sprintf(name, "p_Procs_%s", module);
+    *handle = dynl_open_binary_warn(name, WARN_MSG);
+  }
+  return *handle;
+}
+
+static inline void* p_ProcGetHandle(p_Proc proc, p_Field field)
+{
+  const char* module =  p_ProcField_2_Module(proc, field);
+
+  if (strcmp(module, "FieldIndep") == 0)
+    return p_ProcInitHandle(&p_procs_handle_FieldIndep, module);
+  else if (strcmp(module, "FieldZp") == 0)
+    return p_ProcInitHandle(&p_procs_handle_FieldZp, module);
+  else if (strcmp(module, "FieldQ") == 0)
+    return p_ProcInitHandle(&p_procs_handle_FieldQ, module);
+  else if (strcmp(module, "FieldGeneral") == 0)
+    return p_ProcInitHandle(&p_procs_handle_FieldGeneral, module);
+  else
+  {
+    assume(0);
+    return NULL;
+  }
+}
+
+
+#define InitSetProcs(f, l, o) ((void)0)
+
+static void* GetGeneralProc(p_Proc proc)
+{
+  switch(proc)
+  {
+      case p_Copy_Proc:
+        return (void *)p_Copy__FieldGeneral_LengthGeneral_OrdGeneral;
+      case p_Delete_Proc:
+        return (void *)p_Delete__FieldGeneral_LengthGeneral_OrdGeneral;
+      case p_ShallowCopyDelete_Proc:
+        return (void *)p_ShallowCopyDelete__FieldGeneral_LengthGeneral_OrdGeneral;
+      case p_Mult_nn_Proc:
+        return (void *)p_Mult_nn__FieldGeneral_LengthGeneral_OrdGeneral;
+      case pp_Mult_nn_Proc:
+        return (void *)pp_Mult_nn__FieldGeneral_LengthGeneral_OrdGeneral;
+      case pp_Mult_mm_Proc:
+        return (void *)pp_Mult_mm__FieldGeneral_LengthGeneral_OrdGeneral;
+      case pp_Mult_mm_Noether_Proc:
+        return (void *)pp_Mult_mm_Noether__FieldGeneral_LengthGeneral_OrdGeneral;
+      case p_Mult_mm_Proc:
+        return (void *)p_Mult_mm__FieldGeneral_LengthGeneral_OrdGeneral;
+      case p_Add_q_Proc:
+        return (void *)p_Add_q__FieldGeneral_LengthGeneral_OrdGeneral;
+      case p_Minus_mm_Mult_qq_Proc:
+        return (void *)p_Minus_mm_Mult_qq__FieldGeneral_LengthGeneral_OrdGeneral;
+      case p_Neg_Proc:
+        return (void *)p_Neg__FieldGeneral_LengthGeneral_OrdGeneral;
+      case pp_Mult_Coeff_mm_DivSelect_Proc:
+        return (void *)pp_Mult_Coeff_mm_DivSelect__FieldGeneral_LengthGeneral_OrdGeneral;
+      case pp_Mult_Coeff_mm_DivSelectMult_Proc:
+        return (void *)pp_Mult_Coeff_mm_DivSelectMult__FieldGeneral_LengthGeneral_OrdGeneral;
+      case p_Merge_q_Proc:
+        return (void *)p_Merge_q__FieldGeneral_LengthGeneral_OrdGeneral;
+      case p_kBucketSetLm_Proc:
+        return (void *)p_kBucketSetLm__FieldGeneral_LengthGeneral_OrdGeneral;
+      case p_Unknown_Proc:
+        break;
+  }
+  dReportBug("p_Unknown_Proc");
+  return NULL;
+}
+
+#ifdef RDEBUG
+#include "omalloc.h"
+
+static char* GetGeneralProcName(p_Proc proc)
+{
+  switch(proc)
+  {
+      case p_Copy_Proc:
+        return "p_Copy__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_Delete_Proc:
+        return "p_Delete__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_ShallowCopyDelete_Proc:
+        return "p_ShallowCopyDelete__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_Mult_nn_Proc:
+        return "p_Mult_nn__FieldGeneral_LengthGeneral_OrdGeneral";
+      case pp_Mult_nn_Proc:
+        return "pp_Mult_nn__FieldGeneral_LengthGeneral_OrdGeneral";
+      case pp_Mult_mm_Proc:
+        return "pp_Mult_mm__FieldGeneral_LengthGeneral_OrdGeneral";
+      case pp_Mult_mm_Noether_Proc:
+        return "pp_Mult_mm_Noether__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_Mult_mm_Proc:
+        return "p_Mult_mm__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_Add_q_Proc:
+        return "p_Add_q__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_Minus_mm_Mult_qq_Proc:
+        return "p_Minus_mm_Mult_qq__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_Neg_Proc:
+        return "p_Neg__FieldGeneral_LengthGeneral_OrdGeneral";
+      case pp_Mult_Coeff_mm_DivSelect_Proc:
+        return "pp_Mult_Coeff_mm_DivSelect__FieldGeneral_LengthGeneral_OrdGeneral";
+      case pp_Mult_Coeff_mm_DivSelectMult_Proc:
+        return "pp_Mult_Coeff_mm_DivSelectMult__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_Merge_q_Proc:
+        return "p_Merge_q__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_kBucketSetLm_Proc:
+        return "p_kBucketSetLm__FieldGeneral_LengthGeneral_OrdGeneral";
+      case p_Unknown_Proc:
+        break;
+  }
+  return "p_Unknown_Proc";
+}
+#endif
+
+
+static void* GetDynamicProc(const char* proc_s, p_Proc proc,
+                            p_Field field, p_Length length, p_Ord ord
+#ifdef RDEBUG
+                     , int get_name = 0
+#endif
+                     )
+{
+  void* proc_ptr = NULL;
+  char proc_name[MAX_PROCNAME_LEN];
+  sprintf(proc_name, "%s__%s_%s_%s", proc_s,
+          p_FieldEnum_2_String(field),
+          p_LengthEnum_2_String(length),
+          p_OrdEnum_2_String(ord));
+  // first, try to get the proc from the kernel
+  proc_ptr = dynl_sym(DYNL_KERNEL_HANDLE, proc_name);
+  if (proc_ptr == NULL)
+  {
+    proc_ptr = dynl_sym_warn(p_ProcGetHandle(proc, field), proc_name, WARN_MSG);
+    // last but not least use general proc
+    if (proc_ptr == NULL)
+    {
+      proc_ptr = GetGeneralProc(proc);
+#ifdef RDEBUG
+      sprintf(proc_name, GetGeneralProcName(proc));
+#endif
+    }
+  }
+#ifdef RDEBUG
+  if (get_name)
+  {
+    char* name = omStrDup(proc_name);
+    omMarkAsStaticAddr(name);
+    return (void*) name;
+  }
+#endif
+  return  proc_ptr;
+}
+
+
+#define DoReallySetProc(what, field, length, ord)           \
+  _p_procs->what = (what##_Proc_Ptr)                        \
+     GetDynamicProc(#what, what##_Proc, field, length, ord)
+
+#ifdef RDEBUG
+#define DoSetProc(what, field, length, ord)                         \
+do                                                                  \
+{                                                                   \
+  if (set_names)                                                    \
+    _p_procs->what = (what##_Proc_Ptr)                              \
+       GetDynamicProc(#what,  what##_Proc, field, length, ord, 1);  \
+  else                                                              \
+    DoReallySetProc(what, field, length, ord);                      \
+}                                                                   \
+while(0)
+#else
+#define DoSetProc DoReallySetProc
+#endif
+
+
+#include "p_Procs_Set.h"
+
+
+
+
Index: kernel/p_Procs_Dynamic.h
===================================================================
--- kernel/p_Procs_Dynamic.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Procs_Dynamic.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,33 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+
+/***************************************************************
+ *  File:    p_Procs_Dynamic.h
+ *  Purpose: Configuration for p_Procs as dynamic library procedures
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *  Version: $Id: p_Procs_Dynamic.h,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+
+#ifndef P_PROCS_DYNAMIC_H
+#define P_PROCS_DYNAMIC_H
+
+// see p_Procs_Impl.h for an explaination of these defines
+#define HAVE_FAST_P_PROCS   5
+#define HAVE_FAST_FIELD     2
+#define HAVE_FAST_ORD 4
+#define HAVE_FAST_ZERO_ORD 2
+
+// stupid hpux -- can not handle sl which are that large
+#ifdef __hpux
+#define HAVE_FAST_LENGTH 3
+#else
+#define HAVE_FAST_LENGTH 4
+#endif
+
+// for the configuration of what goes into the kenel and what into
+// shared libs, see p_Procs_Generate.cc:IsKernelProc(...)
+
+#endif // P_PROCS_DYNAMC_H
+
Index: kernel/p_Procs_Generate.cc
===================================================================
--- kernel/p_Procs_Generate.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Procs_Generate.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,312 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_ProcsGenerate.cc
+ *  Purpose: generate p_Procs*.inc at compile
+ *  Note:    this file is included by p_Procs.cc
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_Procs_Generate.cc,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "mod2.h"
+#include "dError.c"
+
+#ifdef p_Procs_Static
+#include "p_Procs_Static.h"
+#else
+#include "p_Procs_Dynamic.h"
+#endif
+
+#include "p_Procs_Impl.h"
+
+#ifndef p_Procs_Static
+int FieldGeneralProcs = 0,
+  FieldIndepProcs = 0,
+  FieldZpProcs = 0,
+  FieldQProcs = 0,
+  KernelProcs = 0,
+  UnknownProcs = 0;
+
+// returns 1, if proc should go into kernel, 0 otherwise
+int IsKernelProc(p_Proc proc, p_Field field, p_Length length, p_Ord ord)
+{
+  // general procs go into kernel
+  if (field == FieldGeneral && length == LengthGeneral && ord == OrdGeneral)
+    return 1;
+
+  // plus procs with FieldZp
+  if ((field == FieldZp || field == FieldQ) &&
+      // which are not general in length or ord
+      !((length == LengthGeneral && p_ProcDependsOn_Length(proc)) ||
+        (ord == OrdGeneral && p_ProcDependsOn_Ord(proc))) &&
+      // and whose length is smaller than five
+      (!p_ProcDependsOn_Length(proc) || (length >= LengthFour)))
+    return 1;
+
+  return 0;
+}
+
+#endif
+
+#define DoSetProc(what, field, length, ord) \
+      GenerateProc(#what, what##_Proc, field, length, ord)
+
+char*** generated_p_procs;
+
+inline int AlreadyHaveProc(p_Proc proc, p_Field field, p_Length length, p_Ord ord)
+{
+  return (generated_p_procs[proc])[index(proc, field, length, ord)] != 0;
+}
+
+const char* macros_field[] = {"n_Copy","n_Delete", "n_Mult", "n_Add", "n_Sub", "n_IsZero", "n_Equal" , "n_Neg", "n_InpMult", NULL};
+
+const char* macros_length[] =
+{"p_MemCopy", "p_MemAdd", "p_MemSum", "p_MemDiff", NULL};
+
+const char* macros_length_ord[] = {"p_MemCmp", NULL};
+int DummyProcs = 0;
+
+int NumberOfHaveProcs = 0;
+
+void AddProc(const char* s_what, p_Proc proc, p_Field field, p_Length length, p_Ord ord)
+{
+  NumberOfHaveProcs++;
+  int i;
+  const char* s_length = p_LengthEnum_2_String(length);
+  const char* s_ord = p_OrdEnum_2_String(ord);
+  const char* s_field = p_FieldEnum_2_String(field);
+  char* s_full_proc_name = (char*) malloc(200);
+
+  sprintf(s_full_proc_name, "%s__%s_%s_%s", s_what, s_field, s_length, s_ord);
+
+  (generated_p_procs[proc])[index(proc, field, length, ord)] = s_full_proc_name;
+  // define all macros
+  printf("\n// definition of %s\n", s_full_proc_name);
+#ifndef p_Procs_Static
+  if (IsKernelProc(proc, field, length, ord))
+  {
+    KernelProcs++;
+    printf("#ifdef p_Procs_Kernel\n");
+  }
+  else
+  {
+    const char* module = p_ProcField_2_Module(proc, field);
+    if (strcmp(module, "FieldGeneral") == 0)
+      FieldGeneralProcs++;
+    else if (strcmp(module, "FieldIndep") == 0)
+      FieldIndepProcs++;
+    else if (strcmp(module, "FieldZp") == 0)
+      FieldZpProcs++;
+    else if (strcmp(module, "FieldQ") == 0)
+      FieldQProcs++;
+    else
+      UnknownProcs++;
+
+    printf("#ifdef p_Procs_%s\n", module);
+  }
+#endif
+  i = 0;
+  while (macros_field[i] != NULL)
+  {
+    printf("#undef %s\n#define %s\t%s_%s\n",
+           macros_field[i], macros_field[i],  macros_field[i], s_field);
+    i++;
+  }
+  i = 0;
+  while (macros_length[i] != NULL)
+  {
+    printf("#undef %s\n#define %s\t%s_%s\n",
+           macros_length[i], macros_length[i], macros_length[i], s_length);
+    i++;
+  }
+  i = 0;
+  while (macros_length_ord[i] != NULL)
+  {
+    printf("#undef %s\n#define %s\t%s_%s_%s\n",
+           macros_length_ord[i], macros_length_ord[i], macros_length_ord[i], s_length, s_ord);
+    i++;
+  }
+
+  // define DECLARE_LENGTH
+  printf("#undef DECLARE_LENGTH\n");
+  printf("#undef p_MemAddAdjust\n");
+  if (length != LengthGeneral)
+  {
+    printf("#define DECLARE_LENGTH(what) ((void)0)\n");
+    printf("#define p_MemAddAdjust(p, r) ((void)0)\n");
+  }
+  else
+  {
+    printf("#define DECLARE_LENGTH(what) what\n");
+    if (proc != pp_Mult_Coeff_mm_DivSelectMult_Proc)
+      printf("#define p_MemAddAdjust(p, r) p_MemAdd_NegWeightAdjust(p, r)\n");
+    else
+      printf("#define p_MemAddAdjust(p, r) ((void)0)\n");
+  }
+
+  // define DECLARE_ORDSGN
+  printf("#undef DECLARE_ORDSGN\n");
+  if (ord != OrdGeneral)
+    printf("#define DECLARE_ORDSGN(what) ((void)0)\n");
+  else
+    printf("#define DECLARE_ORDSGN(what) what\n");
+
+  if (proc == pp_Mult_Coeff_mm_DivSelectMult_Proc)
+  {
+    printf("#undef DECLARE_LENGTH_2\n");
+    printf("#undef p_MemCmp_Bitmask_2\n");
+    if (length != LengthGeneral)
+    {
+      printf("#define DECLARE_LENGTH_2(what) ((void)0)\n");
+      if (length < LengthTwo)
+        printf("#define p_MemCmp_Bitmask_2 p_MemCmp_Bitmask_%s\n", p_LengthEnum_2_String((p_Length) ((int) length + 2)));
+      else
+      printf("#define p_MemCmp_Bitmask_2 p_MemCmp_Bitmask_LengthZero\n");
+    }
+    else
+    {
+      printf("#define DECLARE_LENGTH_2(what) what \n");
+      printf("#define p_MemCmp_Bitmask_2 p_MemCmp_Bitmask_LengthGeneral\n");
+    }
+
+
+    printf("#undef p_MemAddAdjust\n");
+    printf("#define p_MemAddAdjust(p, r) ((void)0)\n");
+  }
+
+  printf("#undef %s\n#define %s %s\n", s_what, s_what, s_full_proc_name);
+  printf("#include \"%s__T.cc\"\n", s_what);
+  printf("#undef %s\n", s_what);
+#ifndef p_Procs_Static
+  printf("#endif // p_Procs_[Kernel|Field*]\n");
+#endif
+}
+
+void GenerateProc(const char* s_what, p_Proc proc, p_Field field, p_Length length, p_Ord ord)
+{
+  if (! AlreadyHaveProc(proc, field, length, ord))
+    AddProc(s_what, proc, field, length, ord);
+}
+
+int main()
+{
+  int field = FieldGeneral;
+  int length  = LengthGeneral;
+  int ord = OrdGeneral;
+  int i;
+
+
+  printf("/* -*-c++-*- */\n");
+  printf("/***************************************************************\n");
+  printf(" * This file was generated automatically by p_ProcsGenerate.cc: DO NOT EDIT\n");
+  printf(" *\n");
+  printf(" * This file provides the needed implementation of p_Procs for\n");
+  printf(" *               %s\n",
+#if defined(p_Procs_Static)
+         "p_Procs_Static"
+#else
+         "p_Procs_Dynamic"
+#endif
+  );
+  printf(" * See the end for a summary.\n");
+  printf(" *******************************************************************/\n");
+
+
+  generated_p_procs = (char***) malloc(p_Unknown_Proc*sizeof(char**));
+  for (i=0; i<p_Unknown_Proc; i++)
+  {
+    generated_p_procs[i] =
+      (char**) calloc(index((p_Proc)i, FieldUnknown, LengthUnknown, OrdUnknown), sizeof(char*));
+  }
+
+  // set default procs
+  for (field = 0; field < (int) FieldUnknown; field++)
+  {
+    for (length=0; length < (int) LengthUnknown; length++)
+    {
+      for (ord=0; ord < (int)OrdUnknown; ord++)
+      {
+        if (IsValidSpec((p_Field) field, (p_Length) length, (p_Ord) ord))
+            SetProcs((p_Field) field, (p_Length) length, (p_Ord) ord);
+      }
+    }
+  }
+
+// we only need lookup tables for p_Procs_Static
+#ifdef p_Procs_Static
+  int j;
+  printf("\n"
+  "/***************************************************************\n"
+  "Names of procs for RDEBUG */\n"
+  "#ifdef RDEBUG\n");
+
+  for (i=0; i<p_Unknown_Proc; i++)
+  {
+    printf("static const char* %s_names[] = {", p_ProcEnum_2_String((p_Proc)i));
+    for (j=0;j<index((p_Proc)i, FieldUnknown, LengthUnknown, OrdUnknown); j++)
+    {
+      char* s = (generated_p_procs[i])[j];
+      if (s != 0)
+      {
+        printf("\n\"%s\",", s);
+      }
+      else
+        printf("0,");
+
+    }
+    printf("\n};\n");
+  }
+  printf("\n #endif // RDEBUG\n\n"
+  "/***************************************************************/\n"
+  "/* Tables for lookup of procedures: */\n");
+
+  for (i=0; i<p_Unknown_Proc; i++)
+  {
+    printf("static const %s_Ptr %s_funcs[] = {", p_ProcEnum_2_String((p_Proc)i), p_ProcEnum_2_String((p_Proc)i));
+    for (j=0;j<index((p_Proc)i, FieldUnknown, LengthUnknown, OrdUnknown); j++)
+    {
+      char* s = (generated_p_procs[i])[j];
+      if (s != 0)
+      {
+        printf("\n%s,", s);
+      }
+      else
+        printf("0,");
+
+    }
+    printf("\n};\n");
+  }
+#endif
+
+  printf("\n/***************************************************************");
+  printf("* Summary:\n");
+  printf("*   HAVE_FAST_P_PROCS  = %d,\n",HAVE_FAST_P_PROCS);
+  printf("*   HAVE_FAST_FIELD    = %d,\n",HAVE_FAST_FIELD);
+  printf("*   HAVE_FAST_LENGTH   = %d,\n",HAVE_FAST_LENGTH);
+  printf("*   HAVE_FAST_ORD      = %d,\n",HAVE_FAST_ORD);
+  printf("*   HAVE_FAST_ZERO_ORD = %d\n",HAVE_FAST_ZERO_ORD);
+  printf("*\n");
+  printf("*   Generated PolyProcs= %d\n",NumberOfHaveProcs);
+
+#ifndef p_Procs_Static
+  printf(" *\n");
+  printf("* KernelProcs          = %d\n",KernelProcs);
+  printf("* FieldIndepProcs      = %d\n",FieldIndepProcs);
+  printf("* FieldZpProcs         = %d\n",FieldZpProcs);
+  printf("* FieldQProcs          = %d\n",FieldQProcs);
+  printf("* FieldGeneralProcs    = %d\n",FieldGeneralProcs);
+  printf("* FieldUnknownProcs    = %d\n",UnknownProcs);
+#endif
+
+  printf("*\n");
+  printf("*******************************************************************/\n");
+}
+
+
Index: kernel/p_Procs_Impl.h
===================================================================
--- kernel/p_Procs_Impl.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Procs_Impl.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,664 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Procs_Impl.h
+ *  Purpose: implementation of primitive procs for polys
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *  Version: $Id: p_Procs_Impl.h,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+#ifndef P_PROCS_IMPL_H
+#define P_PROCS_IMPL_H
+
+/***************************************************************
+ *  
+ * Configurations
+ * 
+ *******************************************************************/
+
+/***************************************************************
+ Here is how it works:
+ At run-time, SetProcs is used to choose the appropriate PolyProcs 
+              based on the ring properies.
+ At generate-time, SetProcs is used to generate all 
+              possible PolyProcs.
+ Which PolyProcs are generated/used can be controled by values of 
+ HAVE_FAST_P_PROCS, HAVE_FAST_LENGTH, HAVE_FAST_ORD, and FAST_FIELD
+ 
+ At generate-time, the file p_Procs.inc is generated,
+ which provides implementations of the p_Procs, based on
+ the p_*_Templates.cc and header files which provide the respective
+ macros.
+
+ At run-time, a fast proc is set/choosen if found/generated, else 
+ a general proc is set/choosen.
+ *******************************************************************/
+
+// Define HAVE_FAST_P_PROCS to:
+//   0 -- only FieldGeneral_LengthGeneral_OrdGeneral
+//   1 -- plus FieldZp_Length*_OrdGeneral procs
+//   2 -- plus FieldZp_Length*_Ord* procs
+//   3 -- plus FieldQ_Length*_Ord*
+//   4 -- plus FieldGeneral_Length*_OrdGeneral procs
+//   5 -- all Field*_Length*_Ord* procs
+#ifndef HAVE_FAST_P_PROCS
+#define HAVE_FAST_P_PROCS 0
+#endif
+
+// Define HAVE_FAST_FIELD to:
+//   0 -- only FieldGeneral
+//   1 -- special cases for FieldZp
+//   2 -- plus special cases for FieldQ
+//   nothing else is implemented, yet
+#ifndef HAVE_FAST_FIELD 
+#define HAVE_FAST_FIELD 0
+#endif
+
+// Define HAVE_FAST_LENGTH to:
+//   0 -- only LengthGeneral
+//   1 -- special cases for length <= 1
+//   2 -- special cases for length <= 2
+//   3 -- special cases for length <= 4
+//   4 -- special cases for length <= 8
+#ifndef HAVE_FAST_LENGTH 
+#define HAVE_FAST_LENGTH 0
+#endif
+
+// Define HAVE_FAST_ORD to:
+//  0  -- only OrdGeneral
+//  1  -- special for ords with n_min <= 1
+//  2  -- special for ords with n_min <= 2
+//  3  -- special ords for with n_min <= 3
+//  4  -- special for all ords
+#ifndef HAVE_FAST_ORD 
+#define HAVE_FAST_ORD 0
+#endif
+
+// Define HAVE_FAST_ZERO_ORD to:
+//  0 -- no zero ords are considered 
+//  1 -- only ZeroOrds for OrdPosNomogPosZero, OrdNomogPosZero, OrdPomogNegZero
+//  2 -- ZeroOrds for all
+#ifndef HAVE_FAST_ZERO_ORD 
+#define HAVE_FAST_ZERO_ORD 0
+#endif
+
+// undefine this, if ExpL_Size always equals CompLSize
+#define HAVE_LENGTH_DIFF
+
+
+// Predicate which returns true if alloc/copy/free of numbers is
+// like that of Zp
+#define ZP_COPY_FIELD(field) \
+  (field == FieldZp || field == FieldGF || field == FieldR)
+
+/***************************************************************
+ *  
+ * Definitions of our fields, lengths, ords, procs we work with
+ * 
+ *******************************************************************/
+
+// Here are the different parameters for setting the PolyProcs:
+
+// If you add/remove things from here, also remeber to adjust the
+// respective *_2_String
+typedef enum p_Field
+{
+  FieldGeneral = 0,
+  FieldZp,          
+  FieldQ,
+  FieldR,
+  FieldGF,
+#if HAVE_MORE_FIELDS_IMPLEMENTED
+  FieldLong_R,
+  FieldLong_C,
+  FieldZp_a,
+  FieldQ_a,
+#endif
+  FieldUnknown
+} p_Field;
+typedef enum p_Length // Length of exponent vector in words
+{
+  LengthGeneral = 0, // n >= 1
+  LengthEight,       // n == 8   
+  LengthSeven,
+  LengthSix,
+  LengthFive,
+  LengthFour,
+  LengthThree,
+  LengthTwo,
+  LengthOne,
+  LengthUnknown
+} p_Length;
+typedef enum p_Ord  
+{                   
+  OrdGeneral = 0,   
+                    //     ordsgn   
+                    //  0   1   i   n-1 n   n_min   Example
+  OrdPomog,         //  +   +   +   +   +   1       (lp,C)
+  OrdNomog,         //  -   -   -   -   -   1       (ls, c), (ds, c)
+#define ORD_MAX_N_1 OrdNomog
+
+#ifdef HAVE_LENGTH_DIFF
+  OrdPomogZero,     //  +   +   +   +   0   2       (Dp, C), Even vars
+  OrdNomogZero,     //  -   -   -   -   0   2       (ds, c), Even vars
+#endif
+
+  OrdNegPomog,      //  -   +   +   +   +   2       (c, lp), (Ds, c)
+  OrdPomogNeg,      //  +   +   +   +   -   2       (lp, c)
+#define ORD_MAX_N_2 OrdPomogNeg
+
+  OrdPosNomog,      //  +   -   -   -   +   3       (dp, c) (for n == 2, use PomogNeg)
+  OrdNomogPos,      //  -   -   -   -   +   3       (ls, C) (for n == 2, use NegPomog)
+
+#ifdef HAVE_LENGTH_DIFF
+  OrdNegPomogZero,  //  -   +   +   +   0   3       (c, lp), (Ds, c)
+  OrdPomogNegZero,  //  +   +   +   -   0   3       (lp, c)
+#endif
+
+  OrdPosPosNomog,   //  +   +   -   -   -   3       (C, dp)
+  OrdPosNomogPos,   //  +   -   -   -   +   3       (dp, C)
+  OrdNegPosNomog,   //  -   +   -   -   -   3       (c, dp)
+#define ORD_MAX_N_3 OrdNegPosNomog
+
+#ifdef HAVE_LENGTH_DIFF
+  OrdNomogPosZero,  //  -   -   -   +   0   4       (ls, C) (for n == 3, use NegPomogZero)
+  OrdPosNomogZero,  //  +   -   -   -   0   4       (dp, c) (for n == 3, use PomogNegZero)
+
+  OrdPosPosNomogZero,// +   +   -   -   0   4       (C, dp)
+  OrdPosNomogPosZero,// +   -   -   +   0   4       (dp, C)
+  OrdNegPosNomogZero,// -   +   -   -   0   4       (c, dp)
+#endif
+
+  OrdUnknown
+} p_Ord;
+
+typedef enum p_Proc
+{
+  p_Copy_Proc = 0,
+  p_Delete_Proc,
+  p_ShallowCopyDelete_Proc,
+  p_Mult_nn_Proc,
+  pp_Mult_nn_Proc,
+  pp_Mult_mm_Proc,
+  pp_Mult_mm_Noether_Proc,
+  p_Mult_mm_Proc,
+  p_Add_q_Proc,
+  p_Minus_mm_Mult_qq_Proc,
+  p_Neg_Proc,
+  pp_Mult_Coeff_mm_DivSelect_Proc,
+  pp_Mult_Coeff_mm_DivSelectMult_Proc,
+  p_Merge_q_Proc,
+  p_kBucketSetLm_Proc,
+  p_Unknown_Proc
+} p_Proc;
+
+static inline char* p_FieldEnum_2_String(p_Field field)
+{
+  switch(field)
+  {
+      case FieldGeneral: return "FieldGeneral";
+      case FieldZp: return "FieldZp";          
+      case FieldQ: return "FieldQ";
+      case FieldR: return "FieldR";
+      case FieldGF: return "FieldGF";
+#if HAVE_MORE_FIELDS_IMPLEMENTED
+      case FieldLong_R: return "FieldLong_R";
+      case FieldLong_C: return "FieldLong_C";
+      case FieldZp_a: return "FieldZp_a";
+      case FieldQ_a: return "FieldQ_a";
+#endif
+      case FieldUnknown: return "FieldUnknown";
+  }
+  return "NoField_2_String";
+}
+
+static inline char* p_LengthEnum_2_String(p_Length length)
+{
+  switch(length)
+  {
+      case LengthGeneral: return "LengthGeneral"; 
+      case LengthEight: return "LengthEight";       
+      case LengthSeven: return "LengthSeven";
+      case LengthSix: return "LengthSix";
+      case LengthFive: return "LengthFive";
+      case LengthFour: return "LengthFour";
+      case LengthThree: return "LengthThree";
+      case LengthTwo: return "LengthTwo";
+      case LengthOne: return "LengthOne";
+      case LengthUnknown: return "LengthUnknown";
+  }
+  return "NoLength_2_String";
+}
+
+static inline char* p_OrdEnum_2_String(p_Ord ord)
+{
+  switch(ord)
+  {
+      case OrdGeneral: return "OrdGeneral";   
+      case OrdPomog: return "OrdPomog";         
+      case OrdNomog: return "OrdNomog";         
+      case OrdNegPomog: return "OrdNegPomog";      
+      case OrdPomogNeg: return "OrdPomogNeg";      
+      case OrdPosNomog: return "OrdPosNomog";      
+      case OrdNomogPos: return "OrdNomogPos";      
+      case OrdPosPosNomog: return "OrdPosPosNomog";   
+      case OrdPosNomogPos: return "OrdPosNomogPos";   
+      case OrdNegPosNomog: return "OrdNegPosNomog";   
+#ifdef HAVE_LENGTH_DIFF
+      case OrdNegPomogZero: return "OrdNegPomogZero";  
+      case OrdPomogNegZero: return "OrdPomogNegZero";  
+      case OrdPomogZero: return "OrdPomogZero";     
+      case OrdNomogZero: return "OrdNomogZero";     
+      case OrdNomogPosZero: return "OrdNomogPosZero";  
+      case OrdPosNomogZero: return "OrdPosNomogZero";  
+      case OrdPosPosNomogZero: return "OrdPosPosNomogZero";
+      case OrdPosNomogPosZero: return "OrdPosNomogPosZero";
+      case OrdNegPosNomogZero: return "OrdNegPosNomogZero";
+#endif
+      case OrdUnknown: return "OrdUnknown";
+  }
+  return "NoOrd_2_String";
+}
+
+static inline char* p_ProcEnum_2_String(p_Proc proc)
+{
+  switch(proc)
+  {
+      case p_Copy_Proc: return "p_Copy_Proc";
+      case p_Delete_Proc: return "p_Delete_Proc";
+      case p_ShallowCopyDelete_Proc: return "p_ShallowCopyDelete_Proc";
+      case p_Mult_nn_Proc: return "p_Mult_nn_Proc";
+      case pp_Mult_nn_Proc: return "pp_Mult_nn_Proc";
+      case pp_Mult_mm_Proc: return "pp_Mult_mm_Proc";
+      case pp_Mult_mm_Noether_Proc: return "pp_Mult_mm_Noether_Proc";
+      case p_Mult_mm_Proc: return "p_Mult_mm_Proc";
+      case p_Add_q_Proc: return "p_Add_q_Proc";
+      case p_Minus_mm_Mult_qq_Proc: return "p_Minus_mm_Mult_qq_Proc";
+      case p_Neg_Proc: return "p_Neg_Proc";
+      case pp_Mult_Coeff_mm_DivSelect_Proc: return "pp_Mult_Coeff_mm_DivSelect_Proc";
+      case pp_Mult_Coeff_mm_DivSelectMult_Proc: return "pp_Mult_Coeff_mm_DivSelectMult_Proc";
+      case p_Merge_q_Proc: return "p_Merge_q_Proc";
+      case p_kBucketSetLm_Proc: return "p_kBucketSetLm_Proc";
+      case p_Unknown_Proc: return "p_Unknown_Proc";
+  }
+  return "NoProc_2_String";
+}
+
+static inline int p_ProcDependsOn_Field(p_Proc proc)
+{
+  if (proc == p_ShallowCopyDelete_Proc ||
+      proc == p_Merge_q_Proc)
+    return 0;
+  return 1;
+}
+
+static inline int p_ProcDependsOn_Ord(p_Proc proc)
+{
+  switch(proc)
+  {
+      case p_Add_q_Proc:
+      case p_Minus_mm_Mult_qq_Proc:
+      case pp_Mult_mm_Noether_Proc:
+      case p_kBucketSetLm_Proc:
+      case p_Merge_q_Proc:
+        return 1;
+        
+      default:
+        return 0;
+  }
+}
+
+static inline int p_ProcDependsOn_Length(p_Proc proc)
+{
+  switch(proc)
+  {
+      case p_Delete_Proc:
+      case p_Mult_nn_Proc:
+      case p_Neg_Proc:
+        return 0;
+        
+      default:
+        return 1;
+  }
+}
+  
+// returns string specifying the module into which the p_Proc
+// should go
+static inline const char* p_ProcField_2_Module(p_Proc proc,  p_Field field)
+{
+  if (! p_ProcDependsOn_Field(proc))
+    return "FieldIndep";
+  else
+  {
+    if (field > FieldQ) field = FieldGeneral;
+    return p_FieldEnum_2_String(field);
+  }
+}
+
+/***************************************************************
+ *  
+ * 
+ * Deal with OrdZero
+ * 
+ *******************************************************************/
+#ifdef HAVE_LENGTH_DIFF
+static inline int IsZeroOrd(p_Ord ord)
+{
+  return (ord == OrdPomogZero || ord == OrdNomogZero ||
+          ord == OrdNegPomogZero || ord == OrdPosNomogZero ||
+          ord == OrdPomogNegZero || ord == OrdNomogPosZero ||
+          ord == OrdPosNomogPosZero || ord == OrdPosPosNomogZero ||
+          ord == OrdNegPosNomogZero);
+}
+
+static inline p_Ord ZeroOrd_2_NonZeroOrd(p_Ord ord, int strict)
+{
+  if (IsZeroOrd(ord))
+  {
+    switch (ord)
+    {
+        case OrdPomogZero:      return OrdPomog;
+        case OrdNomogZero:      return OrdNomog;
+        case OrdNegPomogZero:   return OrdNegPomog;
+        case OrdPosNomogZero:   return OrdPosNomog;
+        case OrdPosPosNomogZero:    return OrdPosPosNomog;
+        case OrdNegPosNomogZero:    return OrdNegPosNomog;
+        default:    
+          if (strict) return OrdGeneral;
+          else if (ord == OrdPomogNegZero) return OrdPomogNeg;
+          else if (ord == OrdNomogPosZero) return OrdNomogPos;
+          else if (ord == OrdPosNomogPosZero) return OrdPosNomogPos;
+          else return OrdGeneral;
+    }
+  }
+  else
+  {
+    return ord;
+  }
+}
+#else
+#define IsZeroOrd(ord) 0
+#define ZeroOrd_2_NonZeroOrd(ord) (ord)
+#endif
+
+/***************************************************************
+ *  
+ * Filters which are applied to field/length/ord, before a proc is 
+ * choosen
+ * 
+ *******************************************************************/
+#ifdef p_Procs_Static
+static inline void StaticKernelFilter(p_Field &field, p_Length &length, 
+                                      p_Ord &ord, const p_Proc proc)
+{
+  // simply exclude some things
+  if ((proc == pp_Mult_mm_Noether_Proc || proc == p_kBucketSetLm_Proc) &&
+      (field != FieldZp))
+  {
+    field = FieldGeneral;
+    length = LengthGeneral;
+    ord = OrdGeneral;
+  }
+}
+#endif
+
+static inline void FastP_ProcsFilter(p_Field &field, p_Length &length, p_Ord &ord, const p_Proc proc)
+{
+  if (HAVE_FAST_P_PROCS >= 5) return;
+  
+  if (HAVE_FAST_P_PROCS < 3 && field == FieldQ)
+    field = FieldGeneral;
+  
+  if ((HAVE_FAST_P_PROCS == 0) ||
+      (HAVE_FAST_P_PROCS <= 4 && field != FieldZp && field != FieldQ &&
+       proc != p_Merge_q_Proc))
+  {
+    field = FieldGeneral;
+    length = LengthGeneral;
+    ord = OrdGeneral;
+    return;
+  }
+  if (HAVE_FAST_P_PROCS == 1 || 
+      (HAVE_FAST_P_PROCS == 4 && field != FieldZp && proc != p_Merge_q_Proc))
+    ord = OrdGeneral;
+}
+
+static inline void FastFieldFilter(p_Field &field)
+{
+  if (HAVE_FAST_FIELD <= 0 || 
+      (HAVE_FAST_FIELD == 1 && field != FieldZp) ||
+      (field != FieldZp && field != FieldQ))
+    field = FieldGeneral;
+}
+      
+static inline void FastLengthFilter(p_Length &length)
+{
+  if ((HAVE_FAST_LENGTH == 3 && length <= LengthFive) ||
+      (HAVE_FAST_LENGTH == 2 && length <= LengthFour) ||
+      (HAVE_FAST_LENGTH == 1 && length <= LengthTwo) ||
+      (HAVE_FAST_LENGTH <= 0))
+  {
+    length = LengthGeneral;
+  }
+}
+
+static inline void FastOrdFilter(p_Ord &ord)
+{
+  if ((HAVE_FAST_ORD == 3 && ord >= OrdNomogPosZero) ||
+      (HAVE_FAST_ORD == 2 && ord >= OrdPosNomog) ||
+      (HAVE_FAST_ORD == 1 && ord >= OrdPomogZero) ||
+      (HAVE_FAST_ORD <= 0))
+    ord = OrdGeneral;
+}
+
+static inline void FastOrdZeroFilter(p_Ord &ord)
+{
+  if (IsZeroOrd(ord))
+  {
+    if ((HAVE_FAST_ZERO_ORD == 1 && (ord != OrdPosNomogPosZero && 
+                                     ord != OrdNomogPosZero && 
+                                     ord != OrdPomogNegZero)) ||
+        (HAVE_FAST_ZERO_ORD <= 0))
+      ord = ZeroOrd_2_NonZeroOrd(ord, 1);
+  }
+}
+
+static inline void NCopy__Filter(p_Field &field)
+{
+  if (ZP_COPY_FIELD(field)) field = FieldZp;
+}
+
+// in p_Add_q, p_MemCmp works with CompLSize,
+// hence, we do not need to consider ZeroOrds
+static inline void p_Add_q__Filter(p_Length &length, p_Ord &ord)
+{
+  if (IsZeroOrd(ord))
+  {
+    ord = ZeroOrd_2_NonZeroOrd(ord, 0);
+    if (length > LengthGeneral)
+    {
+      length = (p_Length) ((int)length + 1);
+    }
+  }
+}
+
+static inline void pp_Mult_mm_Noether_Filter(p_Field &field, 
+                                             p_Length &length, p_Ord &ord)
+{
+  if (ord == OrdPomog 
+      || ord == OrdPomogZero
+      || (ord == OrdPomogNeg && length > LengthTwo) 
+#ifdef HAVE_LENGTH_DIFF
+      || (ord == OrdPomogZero)
+      || (ord == OrdPomogNegZero && length > LengthThree)
+#endif
+      )
+  {
+    // all the other orderings might occur (remeber Mixed Orderings!)
+    field = FieldGeneral;
+    ord = OrdGeneral;
+    length = LengthGeneral;
+  }
+}
+      
+static inline void FastProcFilter(p_Proc proc, p_Field &field, 
+                                  p_Length &length, p_Ord &ord)
+{
+  switch(proc)
+  {
+      case p_Add_q_Proc:
+      case p_Merge_q_Proc:
+        p_Add_q__Filter(length, ord);
+        break;
+        
+      case p_Copy_Proc:
+      case p_Delete_Proc:
+        NCopy__Filter(field);
+        break;
+        
+      case pp_Mult_mm_Noether_Proc:
+        pp_Mult_mm_Noether_Filter(field, length, ord);
+        break;
+
+        case pp_Mult_Coeff_mm_DivSelectMult_Proc:
+          if (length == LengthOne || length == LengthTwo)
+          {
+            field = FieldGeneral;
+            length = LengthGeneral;
+            ord = OrdGeneral;
+            return;
+          }
+          break;
+          
+      default: break;
+  }
+
+  FastOrdFilter(ord);
+  FastOrdZeroFilter(ord);
+  FastLengthFilter(length);
+  FastFieldFilter(field);
+  FastP_ProcsFilter(field, length, ord, proc);
+#ifdef p_Procs_Static
+  StaticKernelFilter(field, length, ord, proc);
+#endif
+}
+
+// returns 1 if combination of field/length/ord is invalid
+static inline int IsValidSpec(p_Field field, p_Length length, p_Ord ord)
+{
+  if (field == FieldUnknown || length == LengthUnknown || ord == OrdUnknown)
+    return 0;
+
+  if (length >= LengthThree && // i.e. 1, 2, or 3
+      ord > ORD_MAX_N_3)       //  i.e. OrdNomogPosZero and below
+    return 0;
+  
+  if (length >= LengthTwo &&    // i.e. 1 or 2
+      ord > ORD_MAX_N_2)        // i.e. PosNomog and below
+    return 0;
+
+  if (length == LengthOne && 
+      ord > ORD_MAX_N_1)           // i.e. PosPomogZero and below
+    return 0;
+
+  // we cover everything for length <= two
+  if (ord == OrdGeneral && length >= LengthTwo)
+    return 0;
+  return 1;
+}
+
+ 
+static inline int index(p_Length length, p_Ord ord)
+{
+  return length*OrdUnknown + ord;
+}
+
+static inline int index(p_Field field, p_Length length)
+{
+  return field*LengthUnknown + length;
+}
+
+static inline int index(p_Field field, p_Length length, p_Ord ord)
+{
+  return field*LengthUnknown*OrdUnknown + length*OrdUnknown + ord;
+}
+
+static inline int index(p_Proc proc, p_Field field, p_Length length, p_Ord ord)
+{
+  switch(proc)
+  {
+      case p_Delete_Proc:
+      case p_Mult_nn_Proc:
+      case p_Neg_Proc:
+        return field;
+        
+      case p_ShallowCopyDelete_Proc:
+        return length;
+        
+      case p_Copy_Proc:
+      case pp_Mult_mm_Proc:
+      case p_Mult_mm_Proc:
+      case pp_Mult_nn_Proc:
+      case pp_Mult_Coeff_mm_DivSelect_Proc:
+      case pp_Mult_Coeff_mm_DivSelectMult_Proc:
+        return index(field, length);
+
+      case p_Add_q_Proc:
+      case p_Minus_mm_Mult_qq_Proc:
+      case pp_Mult_mm_Noether_Proc:
+      case p_kBucketSetLm_Proc:
+        return index(field, length, ord);
+        
+      case p_Merge_q_Proc:
+        return index(length, ord);
+        
+      default:
+        assume(0);
+        return -1;
+  }
+}
+
+
+
+/***************************************************************
+ * 
+ * Macros for setting procs -- these are used for 
+ * generation and setting
+ *
+ ***************************************************************/
+
+#define SetProc(what, field, length, ord)                   \
+do                                                          \
+{                                                           \
+  p_Field t_field = field;                                  \
+  p_Ord t_ord = ord;                                        \
+  p_Length t_length = length;                               \
+  FastProcFilter(what##_Proc, t_field, t_length, t_ord);    \
+  DoSetProc(what, t_field, t_length, t_ord);                \
+}                                                           \
+while (0)                                                   \
+  
+#define SetProcs(field, length, ord)                                    \
+do                                                                      \
+{                                                                       \
+  SetProc(p_Delete, field, LengthGeneral, OrdGeneral);                  \
+  SetProc(p_Mult_nn, field, LengthGeneral, OrdGeneral);                 \
+  SetProc(pp_Mult_nn, field, length, OrdGeneral);                       \
+  SetProc(p_ShallowCopyDelete, FieldGeneral, length, OrdGeneral);       \
+  SetProc(p_Copy, field, length, OrdGeneral);                           \
+  SetProc(pp_Mult_mm, field, length, OrdGeneral);                       \
+  SetProc(pp_Mult_mm_Noether, field, length, ord);                      \
+  SetProc(p_Mult_mm, field, length, OrdGeneral);                        \
+  SetProc(p_Add_q, field, length, ord);                                 \
+  SetProc(p_Minus_mm_Mult_qq, field, length, ord);                      \
+  SetProc(p_kBucketSetLm, field, length, ord);                          \
+  SetProc(p_Neg, field, LengthGeneral, OrdGeneral);                     \
+  SetProc(pp_Mult_Coeff_mm_DivSelect, field, length, OrdGeneral);       \
+  SetProc(pp_Mult_Coeff_mm_DivSelectMult, field, length, OrdGeneral);   \
+  SetProc(p_Merge_q, FieldGeneral, length, ord);                        \
+}                                                                       \
+while (0)
+
+#endif // P_PROCS_IMPL_H
+
Index: kernel/p_Procs_Lib.cc
===================================================================
--- kernel/p_Procs_Lib.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Procs_Lib.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,23 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Procs_Lib.cc
+ *  Purpose: source for shared library of p_Procs
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *  Version: $Id: p_Procs_Lib.cc,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+#include "mod2.h"
+#include "structs.h"
+#include "p_polys.h"
+#include "ring.h"
+#include "p_Procs.h"
+#include "p_Numbers.h"
+#include "p_MemCmp.h"
+#include "p_MemAdd.h"
+#include "p_MemCopy.h"
+#include "kbuckets.h"
+
+#include "p_Procs_Dynamic.inc"
+
Index: kernel/p_Procs_Set.h
===================================================================
--- kernel/p_Procs_Set.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Procs_Set.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,194 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_ProcsSet.h
+ *  Purpose: Procedures for setting p_Procs at run time
+ *  Note:    this file is included by p_Procs_Dynamic/Static.cc
+ *           The macros
+ *              DoSetProc(what, field, length, ord)
+ *              InitSetProc(field, length ord)
+ *           have to be defined before this file is included
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *  Version: $Id: p_Procs_Set.h,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+
+// extract p_Procs properties from a ring
+static inline p_Field p_FieldIs(ring r)
+{
+  if (rField_is_Zp(r))
+#ifdef NV_OPS
+  {
+    if (r->ch<=NV_MAX_PRIME) return FieldZp;
+    else                     return FieldGeneral;
+  }
+#else
+    return FieldZp;
+#endif
+  if (rField_is_R(r)) return FieldR;
+  if (rField_is_GF(r)) return FieldGF;
+  if (rField_is_Q(r)) return FieldQ;
+#ifdef HAVE_MORE_FIELDS_IMPLEMENTED
+  if (rField_is_long_R(r)) return FieldLong_R;
+  if (rField_is_long_C(r)) return FieldLong_C;
+  if (rField_is_Zp_a(r)) return FieldZp_a;
+  if (rField_is_Q_a(r)) return FieldQ_a;
+#endif
+  return FieldGeneral;
+}
+
+static inline p_Length p_LengthIs(ring r)
+{
+  assume(r->ExpL_Size > 0);
+  // here is a quick hack to take care of p_MemAddAdjust
+  if (r->NegWeightL_Offset != NULL) return LengthGeneral;
+  if (r->ExpL_Size == 1) return LengthOne;
+  if (r->ExpL_Size == 2) return LengthTwo;
+  if (r->ExpL_Size == 3) return LengthThree;
+  if (r->ExpL_Size == 4) return LengthFour;
+  if (r->ExpL_Size == 5) return LengthFive;
+  if (r->ExpL_Size == 6) return LengthSix;
+  if (r->ExpL_Size == 7) return LengthSeven;
+  if (r->ExpL_Size == 8) return LengthEight;
+  return LengthGeneral;
+}
+
+static inline int p_IsNomog(long* sgn, int l)
+{
+  int i;
+  for (i=0;i<l;i++)
+    if (sgn[i] > 0) return 0;
+
+  return 1;
+}
+
+static inline int p_IsPomog(long* sgn, int l)
+{
+  int i;
+  for (i=0;i<l;i++)
+    if (sgn[i] < 0) return 0;
+  return 1;
+}
+
+static inline p_Ord p_OrdIs(ring r)
+{
+  long* sgn = r->ordsgn;
+  long l = r->ExpL_Size;
+  int zero = 0;
+
+  if (sgn[l-1] == 0)
+  {
+    l--;
+    zero = 1;
+  }
+
+  // we always favour the pomog cases
+  if (p_IsPomog(sgn,l)) return (zero ? OrdPomogZero : OrdPomog);
+  if (p_IsNomog(sgn,l)) return (zero ? OrdNomogZero : OrdNomog);
+
+  assume(l > 1);
+
+  if (sgn[0] == -1 && p_IsPomog(&sgn[1], l-1))
+    return (zero ? OrdNegPomogZero : OrdNegPomog);
+  if (sgn[l-1] == -1 && p_IsPomog(sgn, l-1))
+    return (zero ? OrdPomogNegZero : OrdPomogNeg);
+
+  if (sgn[0] == 1 && p_IsNomog(&sgn[1], l-1))
+    return (zero ? OrdPosNomogZero : OrdPosNomog);
+  if (sgn[l-1] == 1 && p_IsNomog(sgn, l-1))
+    return (zero ? OrdNomogPosZero : OrdNomogPos);
+
+  assume(l > 2);
+
+  if (sgn[0] == 1 && sgn[1] == 1 && p_IsNomog(&sgn[2], l-2))
+    return (zero ? OrdPosPosNomogZero : OrdPosPosNomog);
+
+  if (sgn[0] == 1 && sgn[l-1] == 1 && p_IsNomog(&sgn[1], l-2))
+    return (zero ? OrdPosNomogPosZero : OrdPosNomogPos);
+
+  if (sgn[0] == -1 && sgn[1] == 1 && p_IsNomog(&sgn[2], l-2))
+    return (zero ? OrdNegPosNomogZero : OrdNegPosNomog);
+
+  return OrdGeneral;
+}
+
+// fields of this struct are set by DoSetProc
+static p_Procs_s *_p_procs;
+
+#ifdef RDEBUG
+// if set, then SetProcs sets only names, instead of functions
+static int set_names = 0;
+#endif
+
+#define CheckProc(which)                                    \
+do                                                          \
+{                                                           \
+  if (p_Procs->which == NULL)                               \
+  {                                                         \
+    dReportBug("p_Procs is NULL");                          \
+    Warn("Singular will work properly, but much slower");   \
+    p_Procs->which = (which##_Proc_Ptr)                     \
+      which##__FieldGeneral_LengthGeneral_OrdGeneral;       \
+  }                                                         \
+}                                                           \
+while (0)
+
+// Choose a set of p_Procs
+void p_ProcsSet(ring r, p_Procs_s* p_Procs)
+{
+  p_Field     field = p_FieldIs(r);
+  p_Length    length = p_LengthIs(r);
+  p_Ord       ord = p_OrdIs(r);
+
+  assume(p_Procs != NULL);
+//#ifdef RDEBUG
+  memset(p_Procs, 0, sizeof(p_Procs_s));
+//#endif
+  _p_procs = p_Procs;
+  assume(IsValidSpec(field, length, ord));
+
+  InitSetProcs(field, length, ord);
+  SetProcs(field, length, ord);
+  CheckProc(p_Copy);
+  CheckProc(p_Delete);
+  CheckProc(p_ShallowCopyDelete);
+  CheckProc(p_Mult_nn);
+  CheckProc(pp_Mult_nn);
+  CheckProc(pp_Mult_mm);
+  CheckProc(pp_Mult_mm_Noether);
+  CheckProc(p_Mult_mm);
+  CheckProc(p_Add_q);
+  CheckProc(p_Minus_mm_Mult_qq);
+  CheckProc(p_Neg);
+  CheckProc(pp_Mult_Coeff_mm_DivSelect);
+  CheckProc(pp_Mult_Coeff_mm_DivSelectMult);
+  CheckProc(p_Merge_q);
+  CheckProc(p_kBucketSetLm);
+
+/*
+  assume(p_Procs->pp_Mult_mm_Noether != pp_Mult_mm_Noether__FieldGeneral_LengthGeneral_OrdGeneral ||
+         p_Procs->p_Minus_mm_Mult_qq == p_Minus_mm_Mult_qq__FieldGeneral_LengthGeneral_OrdGeneral ||
+         r->OrdSgn == 1 || r->LexOrder);
+*/
+}
+
+#ifdef RDEBUG
+void p_Debug_GetSpecNames(const ring r, char* &field, char* &length, char* &ord)
+{
+  p_Field     e_field = p_FieldIs(r);
+  p_Length    e_length = p_LengthIs(r);
+  p_Ord       e_ord = p_OrdIs(r);
+
+  field  = p_FieldEnum_2_String(p_FieldIs(r));
+  length = p_LengthEnum_2_String(p_LengthIs(r));
+  ord    = p_OrdEnum_2_String(p_OrdIs(r));
+}
+
+void p_Debug_GetProcNames(const ring r, p_Procs_s* p_Procs)
+{
+  set_names = 1;
+  p_ProcsSet(r, p_Procs);
+  set_names = 0;
+}
+#endif // RDEBUG
Index: kernel/p_Procs_Static.cc
===================================================================
--- kernel/p_Procs_Static.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Procs_Static.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,63 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Procs_Static.cc
+ *  Purpose: source for static version of p_Procs
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *  Version: $Id: p_Procs_Static.cc,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+#include "mod2.h"
+#include "structs.h"
+#include "p_polys.h"
+#include "ring.h"
+#include "p_Procs.h"
+#include "p_Numbers.h"
+#include "p_MemCmp.h"
+#include "p_MemAdd.h"
+#include "p_MemCopy.h"
+#include "kbuckets.h"
+#include "dError.h"
+
+BOOLEAN p_procs_dynamic = FALSE;
+
+#define p_Procs_Static
+#include "p_Procs_Static.inc"
+
+// include generated configuration
+#include "p_Procs_Static.h"
+// include general p_Proc stuff
+#include "p_Procs_Impl.h"
+
+// define DoSetProc and InitSetProcs
+#define SetStaticProcFromArray(what, type, field, length, ord) \
+  _p_procs->what = (what##_Proc_Ptr) \
+    what##_Proc_##type [index(what##_Proc, field, length, ord)]
+
+#define SetStaticProcFromFuncsArray(what, field, length, ord) \
+  SetStaticProcFromArray(what, funcs, field, length, ord)
+
+#ifdef RDEBUG
+#define DoSetProc(what, field, length, ord)                     \
+do                                                              \
+{                                                               \
+  if (set_names)                                                \
+    SetStaticProcFromArray(what, names, field, length, ord);    \
+  else                                                          \
+    SetStaticProcFromFuncsArray(what, field, length, ord);      \
+}                                                               \
+while(0)
+#else
+#define DoSetProc SetStaticProcFromFuncsArray
+#endif
+
+#define InitSetProcs(f, l, o) ((void)0)
+
+// include routines for setting p_ProcsSet
+
+#include "p_Procs_Set.h"
+
+
+
+
Index: kernel/p_Procs_Static.h
===================================================================
--- kernel/p_Procs_Static.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_Procs_Static.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,54 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Procs_Static.h
+ *  Purpose: Configuration for static p_Procs
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *  Version: $Id: p_Procs_Static.h,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+
+#ifndef P_PROCS_STATIC_H
+#define P_PROCS_STATIC_H
+
+// Set HAVE_FAST_P_PROCS to:
+//   0 -- only FieldGeneral_LengthGeneral_OrdGeneral
+//   1 -- plus FieldZp_Length*_OrdGeneral procs
+//   2 -- plus FieldZp_Length*_Ord* procs
+//   3 -- plus FieldQ_Length*_Ord*
+//   4 -- plus FieldGeneral_Length*_OrdGeneral procs
+//   5 -- all Field*_Length*_Ord* procs
+#define HAVE_FAST_P_PROCS 3
+
+// Set HAVE_FAST_FIELD to:
+//   0 -- only FieldGeneral
+//   1 -- special cases for FieldZp
+//   2 -- plus special cases for FieldQ
+//   nothing else is implemented, yet
+#define HAVE_FAST_FIELD 2
+
+// Set HAVE_FAST_LENGTH to:
+//   0 -- only LengthGeneral
+//   1 -- special cases for length <= 1
+//   2 -- special cases for length <= 2
+//   3 -- special cases for length <= 4
+//   4 -- special cases for length <= 8
+#define HAVE_FAST_LENGTH 3
+
+// Set HAVE_FAST_ORD to:
+//  0  -- only OrdGeneral
+//  1  -- special for ords with n_min <= 1
+//  2  -- special for ords with n_min <= 2
+//  3  -- special ords for with n_min <= 3
+//  4  -- special for all ords
+#define HAVE_FAST_ORD 4
+
+// Set HAVE_FAST_ZERO_ORD to:
+//  0 -- no zero ords are considered
+//  1 -- only ZeroOrds for OrdPosNomogPosZero, OrdNomogPosZero, OrdPomogNegZero
+//  2 -- ZeroOrds for all
+#define HAVE_FAST_ZERO_ORD 1
+
+// on top of all this, see the StaticKernelFilter in p_Procs_Impl.h
+#endif
Index: kernel/p_ShallowCopyDelete__T.cc
===================================================================
--- kernel/p_ShallowCopyDelete__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_ShallowCopyDelete__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,40 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_ShallowCopyDelete__Template.cc
+ *  Purpose: template for p_ShallowCopyDelete
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_ShallowCopyDelete__T.cc,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+
+/***************************************************************
+ *
+ * Destroys: p
+ * Assumes:  Monoms of p are from
+ * Returns:
+ ***************************************************************/
+LINKAGE poly p_ShallowCopyDelete(poly s_p, const ring r, omBin d_bin)
+{
+  spolyrec dp;
+  poly d_p = &dp;
+  unsigned long* s_e;
+  poly h;
+
+  DECLARE_LENGTH(const unsigned long length = r->ExpL_Size);
+
+  while (s_p != NULL)
+  {
+    p_AllocBin(d_p->next, d_bin, r);
+    pIter(d_p);
+    pSetCoeff0(d_p, pGetCoeff(s_p));
+    h = s_p;
+    s_p =  pNext(s_p);
+    p_MemCopy(d_p->exp, h->exp, length);
+    p_FreeBinAddr(h, r);
+  }
+  pNext(d_p) = NULL;
+  return dp.next;
+}
+
Index: kernel/p_kBucketSetLm__T.cc
===================================================================
--- kernel/p_kBucketSetLm__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_kBucketSetLm__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,111 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_KBucketSetLm__Template.cc
+ *  Purpose: template for setting the Lm of a bucket
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 12/00
+ *  Version: $Id: p_kBucketSetLm__T.cc,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+#undef USE_COEF_BUCKETS
+#ifdef HAVE_COEF_BUCKETS
+#define USE_COEF_BUCKETS
+#endif
+
+#ifdef USE_COEF_BUCKETS
+#define MULTIPLY_BUCKET(B,I) do                                        \
+  { if (B->coef[I]!=NULL)                                              \
+    {                                                                  \
+      B->buckets[I]=p_Mult_q(B->buckets[I],B->coef[I],B->bucket_ring); \
+      B->coef[I]=NULL;                                                 \
+    }                                                                  \
+  } while(0)
+#else
+#define MULTIPLY_BUCKET(B,I)
+#endif
+LINKAGE void p_kBucketSetLm(kBucket_pt bucket)
+{
+  int j = 0;
+  poly lt;
+  BOOLEAN zero = FALSE;
+  ring r = bucket->bucket_ring;
+  assume(bucket->buckets[0] == NULL && bucket->buckets_length[0] == 0);
+  DECLARE_LENGTH(const unsigned long length = r->ExpL_Size);
+  DECLARE_ORDSGN(const long* ordsgn = r->ordsgn);
+  poly p;
+
+  do
+  {
+    j = 0;
+    for (int i = 1; i<=bucket->buckets_used; i++)
+    {
+      if (bucket->buckets[i] != NULL)
+      {
+        MULTIPLY_BUCKET(bucket,i);
+        p =  bucket->buckets[j];
+        if (j == 0)
+        {
+          if (p != NULL) goto Greater;
+          j = i;
+          goto Continue;
+        }
+        assume(p != NULL);
+        p_MemCmp(bucket->buckets[i]->exp, p->exp, length, ordsgn, goto Equal, goto Greater, goto Continue);
+
+        Greater:
+        {
+          if (n_IsZero(pGetCoeff(p), r))
+          {
+            n_Delete(&pGetCoeff(p), r);
+            pIter(bucket->buckets[j]);
+            p_FreeBinAddr(p, r);
+            (bucket->buckets_length[j])--;
+          }
+          j = i;
+          goto Continue;
+        }
+
+        Equal:
+        {
+          MULTIPLY_BUCKET(bucket,i);
+          number tn = pGetCoeff(p);
+          pSetCoeff0(p, n_Add(pGetCoeff(bucket->buckets[i]), tn, r));
+          n_Delete(&tn, r);
+          p = bucket->buckets[i];
+          pIter(bucket->buckets[i]);
+          n_Delete(&pGetCoeff(p), r);
+          p_FreeBinAddr(p, r);
+          (bucket->buckets_length[i])--;
+        }
+
+        Continue:;
+      }
+    }
+    p = bucket->buckets[j];
+    if (j > 0 && n_IsZero(pGetCoeff(p), r))
+    {
+      n_Delete(&pGetCoeff(p), r);
+      pIter(bucket->buckets[j]);
+      p_FreeBinAddr(p, r);
+      (bucket->buckets_length[j])--;
+      j = -1;
+    }
+  }
+  while (j < 0);
+
+  if (j == 0)
+  {
+    return;
+  }
+
+  assume(bucket->buckets[j] != NULL);
+  lt = bucket->buckets[j];
+  bucket->buckets[j] = pNext(lt);
+  bucket->buckets_length[j]--;
+  pNext(lt) = NULL;
+  bucket->buckets[0] = lt;
+  bucket->buckets_length[0] = 1;
+
+  kBucketAdjustBucketsUsed(bucket);
+}
Index: kernel/p_polys.cc
===================================================================
--- kernel/p_polys.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_polys.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,862 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_polys.cc
+ *  Purpose: implementation of currRing independent poly procedures
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: p_polys.cc,v 1.1.1.1 2003-10-06 12:15:55 Singular Exp $
+ *******************************************************************/
+
+#include "mod2.h"
+#include "structs.h"
+#include "p_polys.h"
+#include "ring.h"
+#include "febase.h"
+
+/***************************************************************
+ *
+ * Completing what needs to be set for the monomial
+ *
+ ***************************************************************/
+// this is special for the syz stuff
+static int* _Components = NULL;
+static long* _ShiftedComponents = NULL;
+static int _ExternalComponents = 0;
+
+void p_Setm_General(poly p, ring r)
+{
+  p_LmCheckPolyRing(p, r);
+  int pos=0;
+  if (r->typ!=NULL)
+  {
+    loop
+    {
+      long ord=0;
+      sro_ord* o=&(r->typ[pos]);
+      switch(o->ord_typ)
+      {
+        case ro_dp:
+        {
+          int a,e;
+          a=o->data.dp.start;
+          e=o->data.dp.end;
+          for(int i=a;i<=e;i++) ord+=p_GetExp(p,i,r);
+          p->exp[o->data.dp.place]=ord;
+          break;
+        }
+        case ro_wp_neg:
+          ord=POLY_NEGWEIGHT_OFFSET;
+          // no break;
+        case ro_wp:
+        {
+          int a,e;
+          a=o->data.wp.start;
+          e=o->data.wp.end;
+          int *w=o->data.wp.weights;
+          for(int i=a;i<=e;i++) ord+=p_GetExp(p,i,r)*w[i-a];
+          p->exp[o->data.wp.place]=ord;
+          break;
+        }
+        case ro_cp:
+        {
+          int a,e;
+          a=o->data.cp.start;
+          e=o->data.cp.end;
+          int pl=o->data.cp.place;
+          for(int i=a;i<=e;i++) { p->exp[pl]=p_GetExp(p,i,r); pl++; }
+          break;
+        }
+        case ro_syzcomp:
+        {
+          int c=p_GetComp(p,r);
+          long sc = c;
+          int* Components = (_ExternalComponents ? _Components :
+                             o->data.syzcomp.Components);
+          long* ShiftedComponents = (_ExternalComponents ? _ShiftedComponents:
+                                     o->data.syzcomp.ShiftedComponents);
+          if (ShiftedComponents != NULL)
+          {
+            assume(Components != NULL);
+            assume(c == 0 || Components[c] != 0);
+            sc = ShiftedComponents[Components[c]];
+            assume(c == 0 || sc != 0);
+          }
+          p->exp[o->data.syzcomp.place]=sc;
+          break;
+        }
+        case ro_syz:
+        {
+          int c=p_GetComp(p, r);
+          if (c > o->data.syz.limit)
+            p->exp[o->data.syz.place] = o->data.syz.curr_index;
+          else if (c > 0)
+            p->exp[o->data.syz.place]= o->data.syz.syz_index[c];
+          else
+          {
+            assume(c == 0);
+            p->exp[o->data.syz.place]= 0;
+          }
+          break;
+        }
+        default:
+          dReportError("wrong ord in rSetm:%d\n",o->ord_typ);
+          return;
+      }
+      pos++;
+      if (pos == r->OrdSize) return;
+    }
+  }
+}
+
+void p_Setm_Syz(poly p, ring r, int* Components, long* ShiftedComponents)
+{
+  _Components = Components;
+  _ShiftedComponents = ShiftedComponents;
+  _ExternalComponents = 1;
+  p_Setm_General(p, r);
+  _ExternalComponents = 0;
+}
+
+// dummy for lp, ls, etc
+void p_Setm_Dummy(poly p, ring r)
+{
+  p_LmCheckPolyRing(p, r);
+}
+
+// for dp, Dp, ds, etc
+void p_Setm_TotalDegree(poly p, ring r)
+{
+  p_LmCheckPolyRing(p, r);
+  p->exp[r->pOrdIndex] = p_ExpVectorQuerSum(p, r);
+}
+
+// for wp, Wp, ws, etc
+void p_Setm_WFirstTotalDegree(poly p, ring r)
+{
+  p_LmCheckPolyRing(p, r);
+  p->exp[r->pOrdIndex] = pWFirstTotalDegree(p, r);
+}
+
+p_SetmProc p_GetSetmProc(ring r)
+{
+  // covers lp, rp, ls,
+  if (r->typ == NULL) return p_Setm_Dummy;
+
+  if (r->OrdSize == 1)
+  {
+    if (r->typ[0].ord_typ == ro_dp &&
+        r->typ[0].data.dp.start == 1 &&
+        r->typ[0].data.dp.end == r->N &&
+        r->typ[0].data.dp.place == r->pOrdIndex)
+      return p_Setm_TotalDegree;
+    if (r->typ[0].ord_typ == ro_wp &&
+        r->typ[0].data.wp.start == 1 &&
+        r->typ[0].data.wp.end == r->N &&
+        r->typ[0].data.wp.place == r->pOrdIndex &&
+        r->typ[0].data.wp.weights == r->firstwv)
+      return p_Setm_WFirstTotalDegree;
+  }
+  return p_Setm_General;
+}
+
+
+/* -------------------------------------------------------------------*/
+/* several possibilities for pFDeg: the degree of the head term       */
+/*2
+* compute the degree of the leading monomial of p
+* the ordering is compatible with degree, use a->order
+*/
+inline long _pDeg(poly a, ring r)
+{
+  p_LmCheckPolyRing(a, r);
+  assume(p_GetOrder(a, r) == pWTotaldegree(a, r));
+  return p_GetOrder(a, r);
+}
+
+long pDeg(poly a, ring r)
+{
+  return _pDeg(a, r);
+}
+
+/*2
+* compute the degree of the leading monomial of p
+* with respect to weigths 1
+* (all are 1 so save multiplications or they are of different signs)
+* the ordering is not compatible with degree so do not use p->Order
+*/
+inline long _pTotaldegree(poly p, ring r)
+{
+  p_LmCheckPolyRing(p, r);
+  return (long) p_ExpVectorQuerSum(p, r);
+}
+long pTotaldegree(poly p, ring r)
+{
+  return (long) _pTotaldegree(p, r);
+}
+
+// pWTotalDegree for weighted orderings
+// whose first block covers all variables
+inline long _pWFirstTotalDegree(poly p, ring r)
+{
+  int i;
+  long sum = 0;
+
+  for (i=1; i<= r->firstBlockEnds; i++)
+  {
+    sum += p_GetExp(p, i, r)*r->firstwv[i-1];
+  }
+  return sum;
+}
+
+long pWFirstTotalDegree(poly p, ring r)
+{
+  return (long) _pWFirstTotalDegree(p, r);
+}
+
+/*2
+* compute the degree of the leading monomial of p
+* with respect to weigths from the ordering
+* the ordering is not compatible with degree so do not use p->Order
+*/
+long pWTotaldegree(poly p, ring r)
+{
+  p_LmCheckPolyRing(p, r);
+  int i, k;
+  long j =0;
+
+  // iterate through each block:
+  for (i=0;r->order[i]!=0;i++)
+  {
+    switch(r->order[i])
+    {
+      case ringorder_wp:
+      case ringorder_ws:
+      case ringorder_Wp:
+      case ringorder_Ws:
+        for (k=r->block0[i];k<=r->block1[i];k++)
+        { // in jedem block:
+          j+= p_GetExp(p,k,r)*r->wvhdl[i][k - r->block0[i]];
+        }
+        break;
+      case ringorder_M:
+      case ringorder_lp:
+      case ringorder_ls:
+      case ringorder_dp:
+      case ringorder_ds:
+      case ringorder_Dp:
+      case ringorder_Ds:
+      case ringorder_rp:
+        for (k=r->block0[i];k<=r->block1[i];k++)
+        {
+          j+= p_GetExp(p,k,r);
+        }
+        break;
+      case ringorder_c:
+      case ringorder_C:
+      case ringorder_S:
+      case ringorder_s:
+      case ringorder_aa:
+        break;
+      case ringorder_a:
+        for (k=r->block0[i];k<=r->block1[i];k++)
+        { // only one line
+          j+= p_GetExp(p,k, r)*r->wvhdl[i][ k- r->block0[i]];
+        }
+        return j;
+#ifndef NDEBUG
+      default:
+        Print("missing order %d in pWTotaldegree\n",r->order[i]);
+        break;
+#endif
+    }
+  }
+  return  j;
+}
+
+int pWeight(int i, ring r)
+{
+  if ((r->firstwv==NULL) || (i>r->firstBlockEnds))
+  {
+    return 1;
+  }
+  return r->firstwv[i-1];
+}
+
+long pWDegree(poly p, ring r)
+{
+  if (r->firstwv==NULL) return pTotaldegree(p, r);
+  p_LmCheckPolyRing(p, r);
+  int i, k;
+  long j =0;
+
+  for(i=1;i<=r->firstBlockEnds;i++)
+    j+=p_GetExp(p, i, r)*r->firstwv[i-1];
+
+  for (;i<=r->N;i++)
+    j+=p_GetExp(p,i, r)*pWeight(i, r);
+
+  return j;
+}
+
+
+/* ---------------------------------------------------------------------*/
+/* several possibilities for pLDeg: the maximal degree of a monomial in p*/
+/*  compute in l also the pLength of p                                   */
+
+/*2
+* compute the length of a polynomial (in l)
+* and the degree of the monomial with maximal degree: the last one
+*/
+long pLDeg0(poly p,int *l, ring r)
+{
+  p_CheckPolyRing(p, r);
+  Exponent_t k= p_GetComp(p, r);
+  int ll=1;
+
+  if (k > 0)
+  {
+    while ((pNext(p)!=NULL) && (p_GetComp(pNext(p), r)==k))
+    {
+      pIter(p);
+      ll++;
+    }
+  }
+  else
+  {
+     while (pNext(p)!=NULL)
+     {
+       pIter(p);
+       ll++;
+     }
+  }
+  *l=ll;
+  return r->pFDeg(p, r);
+}
+
+/*2
+* compute the length of a polynomial (in l)
+* and the degree of the monomial with maximal degree: the last one
+* but search in all components before syzcomp
+*/
+long pLDeg0c(poly p,int *l, ring r)
+{
+  assume(p!=NULL);
+#ifdef PDEBUG
+  _p_Test(p,r,PDEBUG);
+#endif
+  p_CheckPolyRing(p, r);
+  long o;
+  int ll=1;
+
+  if (! rIsSyzIndexRing(r))
+  {
+    while (pNext(p) != NULL)
+    {
+      pIter(p);
+      ll++;
+    }
+    o = r->pFDeg(p, r);
+  }
+  else
+  {
+    int curr_limit = rGetCurrSyzLimit(r);
+    poly pp = p;
+    while ((p=pNext(p))!=NULL)
+    {
+      if (p_GetComp(p, r)<=curr_limit/*syzComp*/)
+        ll++;
+      else break;
+      pp = p;
+    }
+#ifdef PDEBUG
+    _p_Test(pp,r,PDEBUG);
+#endif
+    o = r->pFDeg(pp, r);
+  }
+  *l=ll;
+  return o;
+}
+
+/*2
+* compute the length of a polynomial (in l)
+* and the degree of the monomial with maximal degree: the first one
+* this works for the polynomial case with degree orderings
+* (both c,dp and dp,c)
+*/
+long pLDegb(poly p,int *l, ring r)
+{
+  p_CheckPolyRing(p, r);
+  Exponent_t k= p_GetComp(p, r);
+  long o = r->pFDeg(p, r);
+  int ll=1;
+
+  if (k != 0)
+  {
+    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
+    {
+      ll++;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p)) !=NULL)
+    {
+      ll++;
+    }
+  }
+  *l=ll;
+  return o;
+}
+
+/*2
+* compute the length of a polynomial (in l)
+* and the degree of the monomial with maximal degree:
+* this is NOT the last one, we have to look for it
+*/
+long pLDeg1(poly p,int *l, ring r)
+{
+  p_CheckPolyRing(p, r);
+  Exponent_t k= p_GetComp(p, r);
+  int ll=1;
+  long  t,max;
+
+  max=r->pFDeg(p, r);
+  if (k > 0)
+  {
+    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
+    {
+      t=r->pFDeg(p, r);
+      if (t>max) max=t;
+      ll++;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p))!=NULL)
+    {
+      t=r->pFDeg(p, r);
+      if (t>max) max=t;
+      ll++;
+    }
+  }
+  *l=ll;
+  return max;
+}
+
+/*2
+* compute the length of a polynomial (in l)
+* and the degree of the monomial with maximal degree:
+* this is NOT the last one, we have to look for it
+* in all components
+*/
+long pLDeg1c(poly p,int *l, ring r)
+{
+  p_CheckPolyRing(p, r);
+  int ll=1;
+  long  t,max;
+
+  max=r->pFDeg(p, r);
+  if (rIsSyzIndexRing(r))
+  {
+    long limit = rGetCurrSyzLimit(r);
+    while ((p=pNext(p))!=NULL)
+    {
+      if (p_GetComp(p, r)<=limit)
+      {
+        if ((t=r->pFDeg(p, r))>max) max=t;
+        ll++;
+      }
+      else break;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p))!=NULL)
+    {
+      if ((t=r->pFDeg(p, r))>max) max=t;
+      ll++;
+    }
+  }
+  *l=ll;
+  return max;
+}
+
+// like pLDeg1, only pFDeg == pDeg
+long pLDeg1_Deg(poly p,int *l, ring r)
+{
+  assume(r->pFDeg == pDeg);
+  p_CheckPolyRing(p, r);
+  Exponent_t k= p_GetComp(p, r);
+  int ll=1;
+  long  t,max;
+
+  max=_pDeg(p, r);
+  if (k > 0)
+  {
+    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
+    {
+      t=_pDeg(p, r);
+      if (t>max) max=t;
+      ll++;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p))!=NULL)
+    {
+      t=_pDeg(p, r);
+      if (t>max) max=t;
+      ll++;
+    }
+  }
+  *l=ll;
+  return max;
+}
+
+long pLDeg1c_Deg(poly p,int *l, ring r)
+{
+  assume(r->pFDeg == pDeg);
+  p_CheckPolyRing(p, r);
+  int ll=1;
+  long  t,max;
+
+  max=_pDeg(p, r);
+  if (rIsSyzIndexRing(r))
+  {
+    long limit = rGetCurrSyzLimit(r);
+    while ((p=pNext(p))!=NULL)
+    {
+      if (p_GetComp(p, r)<=limit)
+      {
+        if ((t=_pDeg(p, r))>max) max=t;
+        ll++;
+      }
+      else break;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p))!=NULL)
+    {
+      if ((t=_pDeg(p, r))>max) max=t;
+      ll++;
+    }
+  }
+  *l=ll;
+  return max;
+}
+
+// like pLDeg1, only pFDeg == pTotoalDegree
+long pLDeg1_Totaldegree(poly p,int *l, ring r)
+{
+  p_CheckPolyRing(p, r);
+  Exponent_t k= p_GetComp(p, r);
+  int ll=1;
+  long  t,max;
+
+  max=_pTotaldegree(p, r);
+  if (k > 0)
+  {
+    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
+    {
+      t=_pTotaldegree(p, r);
+      if (t>max) max=t;
+      ll++;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p))!=NULL)
+    {
+      t=_pTotaldegree(p, r);
+      if (t>max) max=t;
+      ll++;
+    }
+  }
+  *l=ll;
+  return max;
+}
+
+long pLDeg1c_Totaldegree(poly p,int *l, ring r)
+{
+  p_CheckPolyRing(p, r);
+  int ll=1;
+  long  t,max;
+
+  max=_pTotaldegree(p, r);
+  if (rIsSyzIndexRing(r))
+  {
+    long limit = rGetCurrSyzLimit(r);
+    while ((p=pNext(p))!=NULL)
+    {
+      if (p_GetComp(p, r)<=limit)
+      {
+        if ((t=_pTotaldegree(p, r))>max) max=t;
+        ll++;
+      }
+      else break;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p))!=NULL)
+    {
+      if ((t=_pTotaldegree(p, r))>max) max=t;
+      ll++;
+    }
+  }
+  *l=ll;
+  return max;
+}
+
+// like pLDeg1, only pFDeg == pWFirstTotalDegree
+long pLDeg1_WFirstTotalDegree(poly p,int *l, ring r)
+{
+  p_CheckPolyRing(p, r);
+  Exponent_t k= p_GetComp(p, r);
+  int ll=1;
+  long  t,max;
+
+  max=_pWFirstTotalDegree(p, r);
+  if (k > 0)
+  {
+    while (((p=pNext(p))!=NULL) && (p_GetComp(p, r)==k))
+    {
+      t=_pWFirstTotalDegree(p, r);
+      if (t>max) max=t;
+      ll++;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p))!=NULL)
+    {
+      t=_pWFirstTotalDegree(p, r);
+      if (t>max) max=t;
+      ll++;
+    }
+  }
+  *l=ll;
+  return max;
+}
+
+long pLDeg1c_WFirstTotalDegree(poly p,int *l, ring r)
+{
+  p_CheckPolyRing(p, r);
+  int ll=1;
+  long  t,max;
+
+  max=_pWFirstTotalDegree(p, r);
+  if (rIsSyzIndexRing(r))
+  {
+    long limit = rGetCurrSyzLimit(r);
+    while ((p=pNext(p))!=NULL)
+    {
+      if (p_GetComp(p, r)<=limit)
+      {
+        if ((t=_pTotaldegree(p, r))>max) max=t;
+        ll++;
+      }
+      else break;
+    }
+  }
+  else
+  {
+    while ((p=pNext(p))!=NULL)
+    {
+      if ((t=_pTotaldegree(p, r))>max) max=t;
+      ll++;
+    }
+  }
+  *l=ll;
+  return max;
+}
+
+/***************************************************************
+ *
+ * Maximal Exponent business
+ *
+ ***************************************************************/
+
+static inline unsigned long
+p_GetMaxExpL2(unsigned long l1, unsigned long l2, ring r,
+              unsigned long number_of_exp)
+{
+  const unsigned long bitmask = r->bitmask;
+  unsigned long ml1 = l1 & bitmask;
+  unsigned long ml2 = l2 & bitmask;
+  unsigned long max = (ml1 > ml2 ? ml1 : ml2);
+  unsigned long j = number_of_exp - 1;
+
+  if (j > 0)
+  {
+    unsigned long mask = bitmask << r->BitsPerExp;
+    while (1)
+    {
+      ml1 = l1 & mask;
+      ml2 = l2 & mask;
+      max |= ((ml1 > ml2 ? ml1 : ml2) & mask);
+      j--;
+      if (j == 0) break;
+      mask = mask << r->BitsPerExp;
+    }
+  }
+  return max;
+}
+
+static inline unsigned long
+p_GetMaxExpL2(unsigned long l1, unsigned long l2, ring r)
+{
+  return p_GetMaxExpL2(l1, l2, r, r->ExpPerLong);
+}
+
+poly p_GetMaxExpP(poly p, ring r)
+{
+  p_CheckPolyRing(p, r);
+  if (p == NULL) return p_Init(r);
+  poly max = p_LmInit(p, r);
+  pIter(p);
+  if (p == NULL) return max;
+  int i, offset;
+  unsigned long l_p, l_max;
+  unsigned long divmask = r->divmask;
+
+  do
+  {
+    offset = r->VarL_Offset[0];
+    l_p = p->exp[offset];
+    l_max = max->exp[offset];
+    // do the divisibility trick to find out whether l has an exponent
+    if (l_p > l_max ||
+        (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
+      max->exp[offset] = p_GetMaxExpL2(l_max, l_p, r);
+
+    for (i=1; i<r->VarL_Size; i++)
+    {
+      offset = r->VarL_Offset[i];
+      l_p = p->exp[offset];
+      l_max = max->exp[offset];
+      // do the divisibility trick to find out whether l has an exponent
+      if (l_p > l_max ||
+          (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
+        max->exp[offset] = p_GetMaxExpL2(l_max, l_p, r);
+    }
+    pIter(p);
+  }
+  while (p != NULL);
+  return max;
+}
+
+unsigned long p_GetMaxExpL(poly p, ring r, unsigned long l_max)
+{
+  unsigned long l_p, divmask = r->divmask;
+  int i;
+
+  while (p != NULL)
+  {
+    l_p = p->exp[r->VarL_Offset[0]];
+    if (l_p > l_max ||
+        (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
+      l_max = p_GetMaxExpL2(l_max, l_p, r);
+    for (i=1; i<r->VarL_Size; i++)
+    {
+      l_p = p->exp[r->VarL_Offset[i]];
+      // do the divisibility trick to find out whether l has an exponent
+      if (l_p > l_max ||
+          (((l_max & divmask) ^ (l_p & divmask)) != ((l_max-l_p) & divmask)))
+        l_max = p_GetMaxExpL2(l_max, l_p, r);
+    }
+    pIter(p);
+  }
+  return l_max;
+}
+
+/***************************************************************
+ *
+ * Misc things
+ *
+ ***************************************************************/
+// returns TRUE, if all monoms have the same component
+BOOLEAN p_OneComp(poly p, ring r)
+{
+  if(p!=NULL)
+  {
+    long i = p_GetComp(p, r);
+    while (pNext(p)!=NULL)
+    {
+      pIter(p);
+      if(i != p_GetComp(p, r)) return FALSE;
+    }
+  }
+  return TRUE;
+}
+
+/*2
+*test if a monomial /head term is a pure power
+*/
+int p_IsPurePower(const poly p, const ring r)
+{
+  int i,k=0;
+
+  for (i=r->N;i;i--)
+  {
+    if (p_GetExp(p,i, r)!=0)
+    {
+      if(k!=0) return 0;
+      k=i;
+    }
+  }
+  return k;
+}
+
+/*2
+* returns a polynomial representing the integer i
+*/
+poly p_ISet(int i, ring r)
+{
+  poly rc = NULL;
+  if (i!=0)
+  {
+    rc = p_Init(r);
+    pSetCoeff0(rc,r->cf->nInit(i));
+    if (r->cf->nIsZero(p_GetCoeff(rc,r)))
+      p_DeleteLm(&rc,r);
+  }
+  return rc;
+}
+
+/*2
+* returns a polynomial representing the number n
+* destroys n
+*/
+poly p_NSet(number n, ring r)
+{
+  if (r->cf->nIsZero(n))
+  {
+    r->cf->cfDelete(&n, r);
+    return NULL;
+  }
+  else
+  {
+    poly rc = p_Init(r);
+    pSetCoeff0(rc,n);
+    return rc;
+  }
+}
+
+/***************************************************************
+ *
+ * p_ShallowDelete
+ *
+ ***************************************************************/
+#undef LINKAGE
+#define LINKAGE
+#undef p_Delete
+#define p_Delete p_ShallowDelete
+#undef n_Delete
+#define n_Delete(n, r) ((void)0)
+
+#include "p_Delete__T.cc"
+
Index: kernel/p_polys.h
===================================================================
--- kernel/p_polys.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/p_polys.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,448 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    p_Polys.h
+ *  Purpose: declaration of poly stuf which are independent of
+ *           currRing
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 9/00
+ *  Version: $Id: p_polys.h,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
+ *******************************************************************/
+#ifndef P_POLYS_H
+#define P_POLYS_H
+
+#include "structs.h"
+#include "polys-impl.h"
+/*
+ Some general remarks:
+ We divide poly operations into roughly 4 categories:
+ Level 2: operations on monomials/polynomials with constant time,
+          or operations which are just dispatchers to other
+          poly routines
+          - implemented in: pInline2.h
+          - debugging only if PDEBUG >= 2
+          - normally inlined, unless PDEBUG >= 2 || NO_INLINE2
+ Level 1: operations on monomials with time proportional to length
+          - implemented in: pInline1.h
+          - debugging only if PDEBUG >= 1
+          - normally inlined, unless PDEBUG >= 1 || NO_INLINE1
+ Level 0: short operations on polynomials with time proportional to
+          length of poly
+          - implemented in pInline0.cc
+          - debugging if PDEBUG
+          - normally _not_ inlined: can be forced with
+            #define DO_PINLINE0
+            #include "pInline0.h"
+ Misc   : operations on polynomials which do not fit in any of the
+          above categories
+          - implemented in: polys*.cc
+          - never inlined
+          - debugging if PDEBUG >= 0
+
+ You can set PDEBUG on a per-file basis, before including "mod2.h" like
+   #define PDEBUG 2
+   #include "mod2.h"
+ However, PDEBUG will only be in effect, if !NDEBUG.
+*/
+
+/***************************************************************
+ *
+ * Primitives for accessing and setting fields of a poly
+ * poly must be != NULL
+ *
+ ***************************************************************/
+// next
+#define pNext(p)            _pNext(p)
+#define pIter(p)            _pIter(p)
+
+// coeff
+#define pGetCoeff(p)        _pGetCoeff(p)
+// deletes old coeff before setting the new one
+#define pSetCoeff0(p,n)     _pSetCoeff0(p,n)
+#define p_GetCoeff(p,r)     _pGetCoeff(p)
+#define p_SetCoeff0(p,n,r)  _pSetCoeff0(p,n)
+// deletes old p->coef and sets new one
+PINLINE2 number p_SetCoeff(poly p, number n, ring r);
+
+// get Order
+PINLINE2 Order_t p_GetOrder(poly p, ring r);
+// don't use this
+PINLINE2 Order_t p_SetOrder(poly p, long order, ring r);
+
+// Component
+#define p_GetComp(p, r)     _p_GetComp(p, r)
+PINLINE2 unsigned long p_SetComp(poly p, unsigned long c, ring r);
+PINLINE2 unsigned long p_IncrComp(poly p, ring r);
+PINLINE2 unsigned long p_DecrComp(poly p, ring r);
+PINLINE2 unsigned long p_AddComp(poly p, unsigned long v, ring r);
+PINLINE2 unsigned long p_SubComp(poly p, unsigned long v, ring r);
+
+// Exponent
+PINLINE2 int p_GetExp(poly p, int v, ring r);
+PINLINE2 int p_SetExp(poly p, int v, int e, ring r);
+PINLINE2 int p_IncrExp(poly p, int v, ring r);
+PINLINE2 int p_DecrExp(poly p, int v, ring r);
+PINLINE2 int p_AddExp(poly p, int v, int ee, ring r);
+PINLINE2 int p_SubExp(poly p, int v, int ee, ring r);
+PINLINE2 int p_MultExp(poly p, int v, int ee, ring r);
+PINLINE2 int p_GetExpSum(poly p1, poly p2, int i, ring r);
+PINLINE2 int p_GetExpDiff(poly p1, poly p2, int i, ring r);
+
+/***************************************************************
+ *
+ * Allocation/Initalization/Deletion
+ * except for pDeleteLm and pHead, all polys must be != NULL
+ *
+ ***************************************************************/
+PINLINE2 poly p_New(ring r);
+PINLINE2 poly p_New(ring r, omBin bin);
+PINLINE1 poly p_Init(ring r);
+PINLINE1 poly p_Init(ring r, omBin bin);
+PINLINE1 poly p_LmInit(poly p, ring r);
+PINLINE1 poly p_LmInit(poly s_p, ring s_r, ring d_p);
+PINLINE1 poly p_LmInit(poly s_p, ring s_r, ring d_p, omBin d_bin);
+PINLINE1 poly p_Head(poly p, ring r);
+PINLINE2 void p_DeleteLm(poly *p, ring r);
+PINLINE2 void p_DeleteLm(poly p, ring r);
+PINLINE2 void p_LmFree(poly p, ring r);
+PINLINE2 void p_LmFree(poly *p, ring r);
+PINLINE2 poly p_LmFreeAndNext(poly p, ring r);
+PINLINE2 void p_LmDelete(poly p, ring r);
+PINLINE2 void p_LmDelete(poly *p, ring r);
+PINLINE2 poly p_LmDeleteAndNext(poly p, ring r);
+
+/***************************************************************
+ *
+ * Operation on ExpVectors: assumes polys != NULL
+ *
+ ***************************************************************/
+// ExpVextor(d_p) = ExpVector(s_p)
+PINLINE1 void p_ExpVectorCopy(poly d_p, poly s_p, ring r);
+// adjustments for negative weights
+PINLINE1 void p_MemAdd_NegWeightAdjust(poly p, ring r);
+PINLINE1 void p_MemSub_NegWeightAdjust(poly p, ring r);
+// ExpVector(p1) += ExpVector(p2)
+PINLINE1 void p_ExpVectorAdd(poly p1, poly p2, ring r);
+// ExpVector(p1) -= ExpVector(p2)
+PINLINE1 void p_ExpVectorSub(poly p1, poly p2, ring r);
+// ExpVector(p1) += ExpVector(p2) - ExpVector(p3)
+PINLINE1 void p_ExpVectorAddSub(poly p1, poly p2, poly p3, ring r);
+// ExpVector(pr) = ExpVector(p1) + ExpVector(p2)
+PINLINE1 void p_ExpVectorSum(poly pr, poly p1, poly p2, ring r);
+// ExpVector(pr) = ExpVector(p1) + ExpVector(p2)
+PINLINE1 void p_ExpVectorDiff(poly pr, poly p1, poly p2, ring r);
+// returns TRUE if ExpVector(p1) == ExpVector(p2), FALSE, otherwise
+PINLINE1 BOOLEAN p_ExpVectorEqual(poly p1, poly p2, ring r);
+// returns sum of all exponents of p
+PINLINE1 unsigned long p_ExpVectorQuerSum(poly p, ring r);
+
+PINLINE1 void p_GetExpV(poly p, int *ev, ring r);
+PINLINE1 void p_SetExpV(poly p, int *ev, ring r);
+
+
+/***************************************************************
+ *
+ * Comparisons: they are all done without regarding coeffs
+ *
+ ***************************************************************/
+PINLINE1 int p_LmCmp(poly p, poly q, ring r);
+#define p_LmCmpAction(p, q, r, actionE, actionG, actionS) \
+  _p_LmCmpAction(p, q, r, actionE, actionG, actionS)
+
+// returns 1 if ExpVector(p)==ExpVector(q): does not compare numbers !!
+#define p_LmEqual(p1, p2, r) p_ExpVectorEqual(p1, p2, r)
+
+// pCmp: args may be NULL
+// returns: (p2==NULL ? 1 : (p1 == NULL ? -1 : p_LmCmp(p1, p2)))
+PINLINE2 int p_Cmp(poly p1, poly p2, ring r);
+
+
+/***************************************************************
+ *
+ * Divisiblity tests, args must be != NULL, except for
+ * pDivisbleBy
+ *
+ ***************************************************************/
+PINLINE1 BOOLEAN p_DivisibleBy(poly a, poly b, ring r);
+PINLINE1 BOOLEAN p_LmDivisibleBy(poly a, poly b, ring r);
+PINLINE1 BOOLEAN p_LmDivisibleByNoComp(poly a, poly b, ring r);
+unsigned long p_GetShortExpVector(poly a, ring r);
+PINLINE1 BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a,
+                                      poly b, unsigned long not_sev_b, ring r);
+
+PINLINE1 BOOLEAN p_DivisibleBy(poly a, ring r_a, poly b, ring r_b);
+PINLINE1 BOOLEAN p_LmDivisibleBy(poly a, ring r_a, poly b, ring r_b);
+PINLINE1 BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a, ring r_a,
+                                      poly b, unsigned long not_sev_b, ring r_b);
+
+/***************************************************************
+ *
+ * Misc things on Lm
+ *
+ ***************************************************************/
+// test if the monomial is a constant as a vector component
+// i.e., test if all exponents are zero
+PINLINE1 BOOLEAN p_LmIsConstantComp(const poly p, const ring r);
+PINLINE1 BOOLEAN p_LmIsConstant(const poly p, const ring r);
+
+// return TRUE, if p_LmExpVectorAdd stays within ExpBound of ring r,
+//       FALSE, otherwise
+PINLINE1 BOOLEAN p_LmExpVectorAddIsOk(const poly p1, const poly p2, ring r);
+
+/***************************************************************
+ *
+ * Misc things on polys
+ *
+ ***************************************************************/
+// return the maximal exponent of p
+PINLINE2 unsigned long p_GetMaxExp(poly p, ring r);
+// return the maximal exponent of p in form of the maximal long var
+unsigned long p_GetMaxExpL(poly p, ring r, unsigned long l_max = 0);
+// return monomial r such that GetExp(r,i) is maximum of all
+// monomials in p; coeff == 0, next == NULL, ord is not set
+poly p_GetMaxExpP(poly p, ring r);
+
+// suppose that l is a long var in r, return maximal exponent of l
+PINLINE2 unsigned long p_GetMaxExp(unsigned long l, ring r);
+// similar, except assume that l constains number_of_exps exponents
+PINLINE2 unsigned long p_GetMaxExp(const unsigned long l, const ring r, const int number_of_exps);
+
+// return the TotalDegree of the long var l
+PINLINE2 unsigned long p_GetTotalDegree(const unsigned long l, const ring r);
+// return the total degree of the long var l containing number_of_exp exponents
+PINLINE2 unsigned long p_GetTotalDegree(const unsigned long l, const ring r, const int number_of_exps);
+
+
+// like the respective p_LmIs* routines, except that p might be empty
+PINLINE1 BOOLEAN p_IsConstantComp(const poly p, const ring r);
+PINLINE1 BOOLEAN p_IsConstant(const poly p, const ring r);
+PINLINE0 BOOLEAN p_IsConstantPoly(const poly p, const ring r);
+
+// return TRUE if all monoms have the same component
+BOOLEAN   p_OneComp(poly p, ring r);
+int       p_IsPurePower(const poly p, const ring r);
+
+// returns the poly representing the integer i
+poly      p_ISet(int i, ring r);
+// returns the poly representing the number n, destroys n
+poly      p_NSet(number n, ring r);
+
+/***************************************************************
+ *
+ * Copying/Deletion of polys: args may be NULL
+ *
+ ***************************************************************/
+// returns a copy of p
+PINLINE2 poly p_Copy(poly p, const ring r);
+// returns a copy of p with Lm(p) from lmRing and Tail(p) from tailRing
+PINLINE2 poly p_Copy(poly p, const ring lmRing, const ring tailRing);
+// deletes *p, and sets *p to NULL
+PINLINE2 void p_Delete(poly *p, const ring r);
+PINLINE2 void p_Delete(poly *p, const ring lmRing, const ring tailRing);
+
+// copys monomials of p, allocates new monomials from bin,
+// deletes monomoals of p
+PINLINE2 poly p_ShallowCopyDelete(poly p, const ring r, omBin bin);
+// simial but does it only for leading monomial
+PINLINE1 poly p_LmShallowCopyDelete(poly p, const ring r, omBin bin);
+// simply deletes monomials, does not free coeffs
+void p_ShallowDelete(poly *p, const ring r);
+
+  
+
+/***************************************************************
+ *
+ * Copying/Deleteion of polys: args may be NULL
+ *  - p/q as arg mean a poly
+ *  - m a monomial
+ *  - n a number
+ *  - pp (resp. qq, mm, nn) means arg is constant
+ *  - p (resp, q, m, n)     means arg is destroyed
+ *
+ ***************************************************************/
+// returns -p, p is destroyed
+PINLINE2 poly p_Neg(poly p, const ring r);
+
+// returns p*n, p is const (i.e. copied)
+PINLINE2 poly pp_Mult_nn(poly p, number n, const ring r);
+// returns p*n, destroys p
+PINLINE2 poly p_Mult_nn(poly p, number n, const ring r);
+PINLINE2 poly p_Mult_nn(poly p, number n, const ring lmRing, const ring tailRing);
+
+// returns p*m, does neither destroy p nor m
+PINLINE2 poly pp_Mult_mm(poly p, poly m, const ring r);
+// returns p*m, destroys p, const: m
+PINLINE2 poly p_Mult_mm(poly p, poly m, const ring r);
+
+// returns p+q, destroys p and q
+PINLINE2 poly p_Add_q(poly p, poly q, const ring r);
+// like p_Add_q, except that if lp == pLength(lp) lq == pLength(lq)
+// then lp == pLength(p+q)
+PINLINE2 poly p_Add_q(poly p, poly q, int &lp, int lq, const ring r);
+
+// return p - m*q, destroys p; const: q,m
+PINLINE2 poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, const ring r);
+// like p_Minus_mm_Mult_qq, except that if lp == pLength(lp) lq == pLength(lq)
+// then lp == pLength(p -m*q)
+PINLINE2 poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,
+                                 poly spNoether, const ring r);
+// returns p + m*q destroys p, const: q, m
+PINLINE2 poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, const ring r);
+
+// returns p + m*q destroys p, const: q, m
+PINLINE2 poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,
+                                const ring r);
+
+// returns p*q, destroys p and q
+PINLINE2 poly p_Mult_q(poly p, poly q, const ring r);
+// returns p*q, does neither destroy p nor q
+PINLINE2 poly pp_Mult_qq(poly p, poly q, const ring r);
+
+// returns p*Coeff(m) for such monomials pm of p, for which m is divisble by pm
+PINLINE2 poly pp_Mult_Coeff_mm_DivSelect(poly p, const poly m, const ring r);
+
+// returns p*Coeff(m) for such monomials pm of p, for which m is divisble by pm
+// if lp is length of p on input then lp is length of returned poly on output
+PINLINE2 poly pp_Mult_Coeff_mm_DivSelect(poly p, int &lp, const poly m, const ring r);
+
+// returns merged p and q, assumes p and q have no monomials which are equal
+PINLINE2 poly p_Merge_q(poly p, poly c, const ring r);
+// sorts p using bucket sort: returns sorted poly
+// assumes that monomials of p are all different
+// reverses it first, if revert == TRUE, use this if input p is "almost" sorted
+// correctly
+PINLINE2 poly p_SortMerge(poly p, const ring r, BOOLEAN revert = FALSE);
+// like SortMerge, except that p may have equal monimals
+PINLINE2 poly p_SortAdd(poly p, const ring r, BOOLEAN revert = FALSE);
+
+/***************************************************************
+ *
+ * Misc stuff
+ *
+ ***************************************************************/
+PINLINE2 void p_Setm(poly p, ring r);
+p_SetmProc p_GetSetmProc(ring r);
+
+// TODO:
+#define p_SetmComp  p_Setm
+
+// sets component of poly a to i, returns length of a
+PINLINE0   int p_SetCompP(poly a, int i, ring r);
+PINLINE0   int p_SetCompP(poly a, int i, ring lmRing, ring tailRing);
+PINLINE0   long p_MaxComp(poly p, ring lmRing, ring tailRing);
+inline long p_MaxComp(poly p,ring lmRing) {return p_MaxComp(p,lmRing,lmRing);}
+PINLINE0   long p_MinComp(poly p, ring lmRing, ring tailRing);
+inline long p_MinComp(poly p,ring lmRing) {return p_MinComp(p,lmRing,lmRing);}
+
+/***************************************************************
+ *
+ * poly things which are independent of ring
+ *
+ ***************************************************************/
+PINLINE0 int       pLength(poly a);
+PINLINE0 poly      pLast(poly a, int &length);
+inline   poly      pLast(poly a) { int l; return pLast(a, l);}
+PINLINE0 poly pReverse(poly p);
+
+
+/***************************************************************
+ *
+ * I/O
+ *
+ ***************************************************************/
+char*     p_String(poly p, ring lmRing, ring tailRing);
+char*     p_String0(poly p, ring lmRing, ring tailRing);
+void      p_Write(poly p, ring lmRing, ring tailRing);
+void      p_Write0(poly p, ring lmRing, ring tailRing);
+void      p_wrp(poly p, ring lmRing, ring tailRing);
+
+PINLINE2 char*     p_String(poly p, ring p_ring);
+PINLINE2 char*     p_String0(poly p, ring p_ring);
+PINLINE2 void      p_Write(poly p, ring p_ring);
+PINLINE2 void      p_Write0(poly p, ring p_ring);
+PINLINE2 void      p_wrp(poly p, ring p_ring);
+
+
+/***************************************************************
+ *
+ * Degree stuff -- see p_polys.cc for explainations
+ *
+ ***************************************************************/
+extern pLDegProc pLDeg;
+extern pFDegProc pFDeg;
+int  pWeight(int i, ring r);
+long pDeg(poly p, ring r);
+long pTotaldegree(poly p, ring r);
+long pWFirstTotalDegree(poly p, ring r);
+long pWTotaldegree(poly p, ring r);
+long pWDegree(poly p, ring r);
+long pLDeg0(poly p,int *l, ring r);
+long pLDeg0c(poly p,int *l, ring r);
+long pLDegb(poly p,int *l, ring r);
+long pLDeg1(poly p,int *l, ring r);
+long pLDeg1c(poly p,int *l, ring r);
+long pLDeg1_Deg(poly p,int *l, ring r);
+long pLDeg1c_Deg(poly p,int *l, ring r);
+long pLDeg1_Totaldegree(poly p,int *l, ring r);
+long pLDeg1c_Totaldegree(poly p,int *l, ring r);
+long pLDeg1_WFirstTotalDegree(poly p,int *l, ring r);
+long pLDeg1c_WFirstTotalDegree(poly p,int *l, ring r);
+
+/***************************************************************
+ *
+ * PDEBUG stuff
+ *
+ ***************************************************************/
+#ifdef PDEBUG
+// Returns TRUE if m is monom of p, FALSE otherwise
+BOOLEAN pIsMonomOf(poly p, poly m);
+// Returns TRUE if p and q have common monoms
+BOOLEAN pHaveCommonMonoms(poly p, poly q);
+
+// p_Check* routines return TRUE if everything is ok,
+// else, they report error message and return false
+
+// check if Lm(p) is from ring r
+BOOLEAN p_LmCheckIsFromRing(poly p, ring r);
+// check if Lm(p) != NULL, r != NULL and initialized && Lm(p) is from r
+BOOLEAN p_LmCheckPolyRing(poly p, ring r);
+// check if all monoms of p are from ring r
+BOOLEAN p_CheckIsFromRing(poly p, ring r);
+// check r != NULL and initialized && all monoms of p are from r
+BOOLEAN p_CheckPolyRing(poly p, ring r);
+// check if r != NULL and initialized
+BOOLEAN p_CheckRing(ring r);
+// only do check if cond
+#define pIfThen(cond, check) do {if (cond) {check;}} while (0)
+
+BOOLEAN _p_Test(poly p, ring r, int level);
+BOOLEAN _p_LmTest(poly p, ring r, int level);
+BOOLEAN _pp_Test(poly p, ring lmRing, ring tailRing, int level);
+
+#define p_Test(p,r)     _p_Test(p, r, PDEBUG)
+#define p_LmTest(p,r)   _p_LmTest(p, r, PDEBUG)
+#define pp_Test(p, lmRing, tailRing)    _pp_Test(p, lmRing, tailRing, PDEBUG)
+
+#else // ! PDEBUG
+
+#define pIsMonomOf(p, q)        (TRUE)
+#define pHaveCommonMonoms(p, q) (TRUE)
+#define p_LmCheckIsFromRing(p,r)  ((void)0)
+#define p_LmCheckPolyRing(p,r)    ((void)0)
+#define p_CheckIsFromRing(p,r)  ((void)0)
+#define p_CheckPolyRing(p,r)    ((void)0)
+#define p_CheckRing(r)          ((void)0)
+#define P_CheckIf(cond, check)  ((void)0)
+
+#define p_Test(p,r)     ((void)0)
+#define p_LmTest(p,r)   ((void)0)
+#define pp_Test(p, lmRing, tailRing) ((void)0)
+
+#endif
+
+#include "pInline2.h"
+#include "pInline1.h"
+
+#endif // P_POLYS_H
+
Index: kernel/pcv.cc
===================================================================
--- kernel/pcv.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/pcv.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,468 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/* $Id: pcv.cc,v 1.1.1.1 2003-10-06 12:16:01 Singular Exp $ */
+/*
+* ABSTRACT: conversion between polys and coef vectors
+*/
+
+#include "mod2.h"
+
+#ifdef HAVE_PCV
+//#if !defined(HAVE_DYNAMIC_LOADING) || defined(BUILD_MODULE)
+
+#include "tok.h"
+#include "ipid.h"
+#include "numbers.h"
+#include "polys.h"
+#include "ideals.h"
+#include "lists.h"
+#include "matpol.h"
+#include "febase.h"
+#include "pcv.h"
+
+static int pcvMaxDegree;
+static int pcvTableSize;
+static int pcvIndexSize;
+static unsigned* pcvTable=NULL;
+static unsigned** pcvIndex=NULL;
+
+lists pcvLAddL(lists l1,lists l2)
+{
+  lists l0=(lists)omAllocBin(slists_bin);
+  int i=l1->nr;
+  if(l1->nr<l2->nr) i=l2->nr;
+  l0->Init(i+1);
+  for(;i>=0;i--)
+  {
+    if(i<=l1->nr&&(l1->m[i].rtyp==POLY_CMD||l1->m[i].rtyp==VECTOR_CMD))
+    {
+      l0->m[i].rtyp=l1->m[i].rtyp;
+      l0->m[i].data=pCopy((poly)l1->m[i].data);
+      if(i<=l2->nr&&l2->m[i].rtyp==l1->m[i].rtyp)
+        l0->m[i].data=pAdd((poly)l0->m[i].data,pCopy((poly)l2->m[i].data));
+    }
+    else
+    if(i<=l2->nr&&(l2->m[i].rtyp==POLY_CMD||l2->m[i].rtyp==VECTOR_CMD))
+    {
+      l0->m[i].rtyp=l2->m[i].rtyp;
+      l0->m[i].data=pCopy((poly)l2->m[i].data);
+    }
+  }
+  return(l0);
+}
+
+lists pcvPMulL(poly p,lists l1)
+{
+  lists l0=(lists)omAllocBin(slists_bin);
+  l0->Init(l1->nr+1);
+  for(int i=l1->nr;i>=0;i--)
+  {
+    if(l1->m[i].rtyp==POLY_CMD)
+    {
+      l0->m[i].rtyp=POLY_CMD;
+      l0->m[i].data=ppMult_qq(p,(poly)l1->m[i].data);
+    }
+  }
+  return(l0);
+}
+
+BOOLEAN pcvLAddL(leftv res,leftv h)
+{
+  if(h&&h->Typ()==LIST_CMD)
+  {
+    lists l1=(lists)h->Data();
+    h=h->next;
+    if(h&&h->Typ()==LIST_CMD)
+    {
+      lists l2=(lists)h->Data();
+      res->rtyp=LIST_CMD;
+      res->data=(void*)pcvLAddL(l1,l2);
+      return FALSE;
+    }
+  }
+  WerrorS("<list>,<list> expected");
+  return TRUE;
+}
+
+BOOLEAN pcvPMulL(leftv res,leftv h)
+{
+  if(h&&h->Typ()==POLY_CMD)
+  {
+    poly p=(poly)h->Data();
+    h=h->next;
+    if(h&&h->Typ()==LIST_CMD)
+    {
+      lists l=(lists)h->Data();
+      res->rtyp=LIST_CMD;
+      res->data=(void*)pcvPMulL(p,l);
+      return FALSE;
+    }
+  }
+  WerrorS("<poly>,<list> expected");
+  return TRUE;
+}
+
+int pcvDeg(poly p)
+{
+  int d=0;
+  for(int i=pVariables;i>=1;i--) d+=pGetExp(p,i);
+  return d;
+}
+
+int pcvMinDeg(poly p)
+{
+  if(!p) return -1;
+  int md=pcvDeg(p);
+  pIter(p);
+  while(p)
+  {
+    int d=pcvDeg(p);
+    if(d<md) md=d;
+    pIter(p);
+  }
+  return md;
+}
+
+int pcvMinDeg(matrix m)
+{
+  int i,j,d;
+  int md=-1;
+  for(i=1;i<=MATROWS(m);i++)
+  {
+    for(j=1;j<=MATCOLS(m);j++)
+    {
+      d=pcvMinDeg(MATELEM(m,i,j));
+      if((d>=0&&md>d)||md==-1) md=d;
+    }
+  }
+  return(md);
+}
+
+BOOLEAN pcvMinDeg(leftv res,leftv h)
+{
+  if(h)
+  {
+    if(h->Typ()==POLY_CMD)
+    {
+      res->rtyp=INT_CMD;
+      res->data=(void*)pcvMinDeg((poly)h->Data());
+      return FALSE;
+    }
+    else
+    if(h->Typ()==MATRIX_CMD)
+    {
+      res->rtyp=INT_CMD;
+      res->data=(void*)pcvMinDeg((matrix)h->Data());
+      return FALSE;
+    }
+  }
+  WerrorS("<poly> expected");
+  return TRUE;
+}
+
+void pcvInit(int d)
+{
+  if(d<0) d=1;
+  pcvMaxDegree=d+1;
+  pcvTableSize=pVariables*pcvMaxDegree*sizeof(unsigned);
+  pcvTable=(unsigned*)omAlloc0(pcvTableSize);
+  pcvIndexSize=pVariables*sizeof(unsigned*);
+  pcvIndex=(unsigned**)omAlloc(pcvIndexSize);
+  for(int i=0;i<pVariables;i++)
+    pcvIndex[i]=pcvTable+i*pcvMaxDegree;
+  for(int i=0;i<pcvMaxDegree;i++)
+    pcvIndex[0][i]=i;
+  unsigned k,l;
+  for(int i=1;i<pVariables;i++)
+  {
+    k=0;
+    for(int j=0;j<pcvMaxDegree;j++)
+    {
+      l=pcvIndex[i-1][j];
+      if(l>unsigned(~0)-k)
+      {
+        j=pcvMaxDegree;
+        i=pVariables;
+        WerrorS("unsigned overflow");
+      }
+      else pcvIndex[i][j]=k+=l;
+    }
+  }
+}
+
+void pcvClean()
+{
+  if(pcvTable)
+  {
+    omFreeSize(pcvTable,pcvTableSize);
+    pcvTable=NULL;
+  }
+  if(pcvIndex)
+  {
+    omFreeSize(pcvIndex,pcvIndexSize);
+    pcvIndex=NULL;
+  }
+}
+
+int pcvM2N(poly m)
+{
+  unsigned n=0,dn,d=0;
+  for(int i=0;i<pVariables;i++)
+  {
+    d+=pGetExp(m,i+1);
+    dn=pcvIndex[i][d];
+    if(dn>MAX_COMPONENT-n)
+    {
+      i=pVariables;
+      WerrorS("component overflow");
+    }
+    else n+=dn;
+  }
+  return n+1;
+}
+
+poly pcvN2M(int n)
+{
+  n--;
+  poly m=pOne();
+  int i,j,k;
+  for(i=pVariables-1;i>=0;i--)
+  {
+    k=j;
+    for(j=0; (j<pcvMaxDegree) && (pcvIndex[i][j]<=(unsigned)n); j++);
+    j--;
+    n-=pcvIndex[i][j];
+    if(i<pVariables-1) pSetExp(m,i+2,k-j);
+  }
+  if(n==0)
+  {
+    pSetExp(m,1,j);
+    pSetm(m);
+    return m;
+  }
+  else
+  {
+    pDeleteLm(&m);
+    return NULL;
+  }
+}
+
+poly pcvP2CV(poly p,int d0,int d1)
+{
+  poly cv=NULL;
+  while(p)
+  {
+    int d=pcvDeg(p);
+    if(d0<=d&&d<d1)
+    {
+      poly c=pNSet(nCopy(pGetCoeff(p)));
+      pSetComp(c,pcvM2N(p));
+      cv=pAdd(cv,c);
+    }
+    pIter(p);
+  }
+  return cv;
+}
+
+poly pcvCV2P(poly cv,int d0,int d1)
+{
+  poly p=NULL;
+  while(cv)
+  {
+    poly m=pcvN2M(pGetComp(cv));
+    if(m)
+    {
+      int d=pcvDeg(m);
+      if(d0<=d&&d<d1)
+      {
+        pSetCoeff(m,nCopy(pGetCoeff(cv)));
+        p=pAdd(p,m);
+      }
+    }
+    pIter(cv);
+  }
+  return p;
+}
+
+lists pcvP2CV(lists pl,int d0,int d1)
+{
+  lists cvl=(lists)omAllocBin(slists_bin);
+  cvl->Init(pl->nr+1);
+  pcvInit(d1);
+  for(int i=pl->nr;i>=0;i--)
+  {
+    if(pl->m[i].rtyp==POLY_CMD)
+    {
+      cvl->m[i].rtyp=VECTOR_CMD;
+      cvl->m[i].data=pcvP2CV((poly)pl->m[i].data,d0,d1);
+    }
+  }
+  pcvClean();
+  return cvl;
+}
+
+lists pcvCV2P(lists cvl,int d0,int d1)
+{
+  lists pl=(lists)omAllocBin(slists_bin);
+  pl->Init(cvl->nr+1);
+  pcvInit(d1);
+  for(int i=cvl->nr;i>=0;i--)
+  {
+    if(cvl->m[i].rtyp==VECTOR_CMD)
+    {
+      pl->m[i].rtyp=POLY_CMD;
+      pl->m[i].data=pcvCV2P((poly)cvl->m[i].data,d0,d1);
+    }
+  }
+  pcvClean();
+  return pl;
+}
+
+BOOLEAN pcvP2CV(leftv res,leftv h)
+{
+  if(currRingHdl)
+  {
+    if(h&&h->Typ()==LIST_CMD)
+    {
+      lists p=(lists)h->Data();
+      h=h->next;
+      if(h&&h->Typ()==INT_CMD)
+      {
+        int d0=(int)h->Data();
+        h=h->next;
+        if(h&&h->Typ()==INT_CMD)
+        {
+          int d1=(int)h->Data();
+          res->rtyp=LIST_CMD;
+          res->data=(void*)pcvP2CV(p,d0,d1);
+          return FALSE;
+        }
+      }
+    }
+    WerrorS("<list>,<int>,<int> expected");
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+BOOLEAN pcvCV2P(leftv res,leftv h)
+{
+  if(currRingHdl)
+  {
+    if(h&&h->Typ()==LIST_CMD)
+    {
+      lists pl=(lists)h->Data();
+      h=h->next;
+      if(h&&h->Typ()==INT_CMD)
+      {
+        int d0=(int)h->Data();
+        h=h->next;
+        if(h&&h->Typ()==INT_CMD)
+        {
+          int d1=(int)h->Data();
+          res->rtyp=LIST_CMD;
+          res->data=(void*)pcvCV2P(pl,d0,d1);
+          return FALSE;
+        }
+      }
+    }
+    WerrorS("<list>,<int>,<int> expected");
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+int pcvDim(int d0,int d1)
+{
+  if(d0<0) d0=0;
+  if(d1<0) d1=0;
+  pcvInit(d1);
+  int d=pcvIndex[pVariables-1][d1]-pcvIndex[pVariables-1][d0];
+  pcvClean();
+  return d;
+}
+
+BOOLEAN pcvDim(leftv res,leftv h)
+{
+  if(currRingHdl)
+  {
+    if(h&&h->Typ()==INT_CMD)
+    {
+      int d0=(int)h->Data();
+      h=h->next;
+      if(h&&h->Typ()==INT_CMD)
+      {
+        int d1=(int)h->Data();
+        res->rtyp=INT_CMD;
+        res->data=(void*)pcvDim(d0,d1);
+        return FALSE;
+      }
+    }
+    WerrorS("<int>,<int> expected");
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+int pcvBasis(lists b,int i,poly m,int d,int n)
+{
+  if(n<pVariables)
+  {
+    for(int k=0,l=d;k<=l;k++,d--)
+    {
+      pSetExp(m,n,k);
+      i=pcvBasis(b,i,m,d,n+1);
+    }
+  }
+  else
+  {
+    pSetExp(m,n,d);
+    pSetm(m);
+    b->m[i].rtyp=POLY_CMD;
+    b->m[i++].data=pCopy(m);
+  }
+  return i;
+}
+
+lists pcvBasis(int d0,int d1)
+{
+  if(d0<0) d0=0;
+  if(d1<0) d1=0;
+  lists b=(lists)omAllocBin(slists_bin);
+  b->Init(pcvDim(d0,d1));
+  poly m=pOne();
+  for(int d=d0,i=0;d<d1;d++)
+    i=pcvBasis(b,i,m,d,1);
+  pDeleteLm(&m);
+  return b;
+}
+
+BOOLEAN pcvBasis(leftv res,leftv h)
+{
+  if(currRingHdl)
+  {
+    if(h&&h->Typ()==INT_CMD)
+    {
+      int d0=(int)h->Data();
+      h=h->next;
+      if(h&&h->Typ()==INT_CMD)
+      {
+        int d1=(int)h->Data();
+        res->rtyp=LIST_CMD;
+        res->data=(void*)pcvBasis(d0,d1);
+        return FALSE;
+      }
+    }
+    WerrorS("<int>,<int> expected");
+    return TRUE;
+  }
+  WerrorS("no ring active");
+  return TRUE;
+}
+
+//#endif /* !defined(HAVE_DYNAMIC_LOADING) || defined(BUILD_MODULE) */
+#endif /* HAVE_PCV */
Index: kernel/pcv.h
===================================================================
--- kernel/pcv.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/pcv.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,38 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: pcv.h,v 1.1.1.1 2003-10-06 12:16:01 Singular Exp $ */
+/*
+* ABSTRACT: conversion between polys and coef vectors
+*/
+
+#ifndef PCV_H
+#define PCV_H
+
+lists pcvLAddL(lists l1,lists l2);
+lists pcvPMulL(poly p,lists l1);
+BOOLEAN pcvLAddL(leftv res,leftv h);
+BOOLEAN pcvPMulL(leftv res,leftv h);
+int pcvDeg(poly p);
+int pcvMinDeg(poly p);
+int pcvMinDeg(matrix m);
+BOOLEAN pcvMinDeg(leftv res,leftv h);
+void pcvInit(int d);
+void pcvClean();
+int pcvM2N(poly m);
+poly pcvN2M(int n);
+poly pcvP2CV(poly p,int d0,int d1);
+poly pcvCV2P(poly cv,int d0,int d1);
+lists pcvP2CV(lists pl,int d0,int d1);
+ideal pcvP2CV(ideal p,int d0,int d1);
+lists pcvCV2P(lists cvl,int d0,int d1);
+ideal pcvCV2P(ideal cv,int d0,int d1);
+BOOLEAN pcvP2CV(leftv res,leftv h);
+BOOLEAN pcvCV2P(leftv res,leftv h);
+int pcvDim(int d0,int d1);
+BOOLEAN pcvDim(leftv res,leftv h);
+int pcvBasis(lists b,int i,poly m,int d,int n);
+lists pcvBasis(int d0,int d1);
+BOOLEAN pcvBasis(leftv res,leftv h);
+
+#endif
Index: kernel/polys-impl.cc
===================================================================
--- kernel/polys-impl.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/polys-impl.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,181 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: polys-impl.cc,v 1.1.1.1 2003-10-06 12:16:01 Singular Exp $ */
+
+/***************************************************************
+ *
+ * File:       polys-impl.cc
+ * Purpose:    low-level procuders for polys.
+ *
+ * If you touch anything here, you better know what you are doing.
+ * What is here should not be used directly from other routines -- the
+ * encapsulations in polys.[h,cc] should be used, instead.
+ *
+ ***************************************************************/
+#ifndef POLYS_IMPL_CC
+#define POLYS_IMPL_CC
+
+#include <stdio.h>
+#include <string.h>
+#include "mod2.h"
+
+#include "omalloc.h"
+#ifdef PDEBUG
+#undef NO_INLINE3
+#define NO_INLINE3
+#endif
+#include "polys-impl.h"
+
+#include "structs.h"
+#include "febase.h"
+#include "numbers.h"
+#include "polys.h"
+#include "ring.h"
+#include "p_Procs.h"
+#include "dError.h"
+
+#ifdef PDEBUG
+int pDBsyzComp=0;
+#endif
+
+/***************************************************************
+ *
+ * Storage Managament Routines
+ *
+ ***************************************************************/
+
+
+void ppDelete(poly* p, ring rg)
+{
+  ring origRing = currRing;
+  rChangeCurrRing(rg);
+  pDelete(p);
+  rChangeCurrRing(origRing);
+}
+
+
+poly pHeadProc(poly p)
+{
+  return pHead(p);
+}
+
+
+static inline unsigned long GetBitFields(Exponent_t e,
+                                         unsigned int s, unsigned int n)
+{
+  unsigned int i = 0, ev = 0;
+  assume(n > 0 && s < BIT_SIZEOF_LONG);
+  do
+  {
+    assume(s+i < BIT_SIZEOF_LONG);
+    if (e > (Exponent_t) i) ev |= Sy_bit(s+i);
+    else break;
+    i++;
+  }
+  while (i < n);
+  return ev;
+}
+
+// Short Exponent Vectors are used for fast divisibility tests
+// ShortExpVectors "squeeze" an exponent vector into one word as follows:
+// Let n = BIT_SIZEOF_LONG / pVariables.
+// If n == 0 (i.e. pVariables > BIT_SIZE_OF_LONG), let m == the number
+// of non-zero exponents. If (m>BIT_SIZEOF_LONG), then sev = ~0, else
+// first m bits of sev are set to 1.
+// Otherwise (i.e. pVariables <= BIT_SIZE_OF_LONG)
+// represented by a bit-field of length n (resp. n+1 for some
+// exponents). If the value of an exponent is greater or equal to n, then
+// all of its respective n bits are set to 1. If the value of an exponent
+// is smaller than n, say m, then only the first m bits of the respective
+// n bits are set to 1, the others are set to 0.
+// This way, we have:
+// exp1 / exp2 ==> (ev1 & ~ev2) == 0, i.e.,
+// if (ev1 & ~ev2) then exp1 does not divide exp2
+unsigned long p_GetShortExpVector(poly p, ring r)
+{
+  assume(p != NULL);
+  if (p == NULL) return 0;
+  unsigned long ev = 0; // short exponent vector
+  unsigned int n = BIT_SIZEOF_LONG / r->N; // number of bits per exp
+  unsigned int m1; // highest bit which is filled with (n+1)
+  unsigned int i = 0, j=1;
+
+  if (n == 0)
+  {
+    if (r->N <2*BIT_SIZEOF_LONG)
+    {
+      n=1;
+      m1=0;
+    }
+    else
+    {
+      for (; j<=(unsigned long) r->N; j++)
+      {
+        if (p_GetExp(p,j,r) > 0) i++;
+        if (i == BIT_SIZEOF_LONG) break;
+      }
+      if (i>0)
+      ev = ~((unsigned long)0) >> ((unsigned long) (BIT_SIZEOF_LONG - i));
+      return ev;
+    }
+  }
+  else
+  {
+    m1 = (n+1)*(BIT_SIZEOF_LONG - n*r->N);
+  }
+
+  n++;
+  while (i<m1)
+  {
+    ev |= GetBitFields(p_GetExp(p, j,r), i, n);
+    i += n;
+    j++;
+  }
+
+  n--;
+  while (i<BIT_SIZEOF_LONG)
+  {
+    ev |= GetBitFields(p_GetExp(p, j,r), i, n);
+    i += n;
+    j++;
+  }
+  return ev;
+}
+
+
+int rComp0_Func(poly p1,poly p2)
+{
+  int i;
+  for(i=0; i< currRing->CmpL_Size;i++)
+  {
+    if (p1->exp[i] != p2->exp[i])
+    {
+      if (p1->exp[i] > p2->exp[i])
+        return currRing->ordsgn[i];
+      else
+        return -currRing->ordsgn[i];
+    }
+  }
+  return 0;
+}
+
+#ifdef PDEBUG
+int rComp0(poly p1,poly p2)
+{
+  int i;
+  for(i=0; i<currRing->CmpL_Size;i++)
+  {
+    if (p1->exp[i] != p2->exp[i])
+    {
+      if (p1->exp[i] > p2->exp[i])
+        return currRing->ordsgn[i];
+      else
+        return -currRing->ordsgn[i];
+    }
+  }
+  return 0;
+}
+#endif
+
+#endif // POLYS_IMPL_CC
Index: kernel/polys-impl.h
===================================================================
--- kernel/polys-impl.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/polys-impl.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,267 @@
+#ifndef POLYS_IMPL_H
+#define POLYS_IMPL_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: polys-impl.h,v 1.1.1.1 2003-10-06 12:16:01 Singular Exp $ */
+
+/***************************************************************
+ *
+ * File:       polys-impl.h
+ * Purpose:    low-level and macro definition of polys
+ *
+ * If you touch anything here, you better know what you are doing.
+ * What is here should not be used directly from other routines -- the
+ * encapsulations in polys.h should be used, instead.
+ *
+ ***************************************************************/
+#include "structs.h"
+#include "omalloc.h"
+
+/***************************************************************
+ *
+ * definition of the poly structure and its fields
+ *
+ ***************************************************************/
+
+#ifndef NDEBUG
+#define VARS (10)   /*max. number of variables as constant*/
+#else
+#define VARS (0)
+#endif
+
+typedef Exponent_t* Exponent_pt;
+struct  spolyrec
+{
+  poly      next;           // next needs to be the first field
+  number    coef;           // and coef the second --- do not change this !!!
+  unsigned long exp[VARS];  // make sure that exp is aligned
+};
+#define POLYSIZE (sizeof(poly) + sizeof(number))
+#define POLYSIZEW (POLYSIZE / sizeof(long))
+#define POLY_NEGWEIGHT_OFFSET 0x80000000
+
+/***************************************************************
+ *
+ * What should be inlined and debugged?
+ *
+ ***************************************************************/
+#ifdef NO_PDEBUG
+#undef PDEBUG
+#endif
+
+// determines inlining of poly procs which iter through polys
+#if defined(DO_PINLINE0) && !defined(PDEBUG)
+#define PINLINE0 static inline
+#else
+#define PINLINE0
+#endif
+
+// determines inlining of poly procs which iter over ExpVector
+#undef NO_PINLINE1
+#if PDEBUG <= 0 && !defined(NO_INLINE1)
+#define PINLINE1 static inline
+#else
+#define PINLINE1
+#define NO_PINLINE1 1
+#endif
+
+// determines inlining of constant time poly procs
+#undef NO_PINLINE2
+#if PDEBUG <= 1 && !defined(NO_INLINE2)
+#define PINLINE2 static inline
+#else
+#define PINLINE2
+#define NO_PINLINE2 1
+#endif
+
+// determines inlining of stuff from polys-impl.h
+#undef NO_PINLINE3
+#if PDEBUG <= 2 && !defined(NO_INLINE3)
+#define PINLINE3 static inline
+#else
+#define PINLINE3
+#define NO_PINLINE3 1
+#endif
+
+/***************************************************************
+ *
+ * prepare debugging
+ *
+ ***************************************************************/
+
+#if defined(PDEBUG)
+
+extern BOOLEAN dPolyReportError(poly p, ring r, const char* fmt, ...);
+
+// macros for checking of polys
+#define pAssumeReturn(cond)                                  \
+do                                                          \
+{                                                           \
+  if (! (cond))                                             \
+  {                                                         \
+    dPolyReportError(NULL, NULL, "pAssume violation of: %s", \
+                 #cond);                                    \
+    return FALSE;                                           \
+  }                                                         \
+}                                                           \
+while (0)
+
+#define pAssume(cond)                                        \
+do                                                          \
+{                                                           \
+  if (! (cond))                                             \
+  {                                                         \
+    dPolyReportError(NULL, NULL, "pAssume violation of: %s", \
+                 #cond);                                    \
+  }                                                         \
+}                                                           \
+while (0)
+
+#define _pPolyAssumeReturn(cond, p, r)                       \
+do                                                          \
+{                                                           \
+  if (! (cond))                                             \
+  {                                                         \
+    dPolyReportError(p, r, "pPolyAssume violation of: %s",   \
+                 #cond);                                    \
+    return FALSE;                                           \
+  }                                                         \
+}                                                           \
+while (0)
+
+#define _pPolyAssume(cond,p,r)                                   \
+do                                                              \
+{                                                               \
+  if (! (cond))                                                 \
+  {                                                             \
+    dPolyReportError(p, r, "pPolyAssume violation of: %s",    \
+                 #cond);                                        \
+  }                                                             \
+}                                                               \
+while (0)
+
+#define _pPolyAssumeReturnMsg(cond, msg, p, r)   \
+do                                              \
+{                                               \
+  if (! (cond))                                 \
+  {                                             \
+    dPolyReportError(p, r, "%s ",  msg);        \
+    return FALSE;                               \
+  }                                             \
+}                                               \
+while (0)
+
+#define pPolyAssume(cond)        _pPolyAssume(cond, p, r)
+#define pPolyAssumeReturn(cond)  _pPolyAssumeReturn(cond, p, r)
+#define pPolyAssumeReturnMsg(cond, msg)  _pPolyAssumeReturnMsg(cond, msg, p, r)
+
+#define pFalseReturn(cond)  do {if (! (cond)) return FALSE;} while (0)
+#if (OM_TRACK > 2) && defined(OM_TRACK_CUSTOM)
+#define p_SetRingOfLm(p, r) omSetCustomOfAddr(p, r)
+void p_SetRingOfLeftv(leftv l, ring r);
+#else
+#define p_SetRingOfLm(p, r) ((void)0)
+#define p_SetRingOfLeftv(l, r) ((void)0)
+#endif
+
+#else // ! defined(PDEBUG)
+#define pFalseReturn(cond)           ((void)0)
+#define pAssume(cond)                ((void)0)
+#define pPolyAssume(cond)            ((void)0)
+#define _pPolyAssume(cond, p,r)      ((void)0)
+#define pAssumeReturn(cond)          ((void)0)
+#define pPolyAssumeReturn(cond)      ((void)0)
+#define _pPolyAssumeReturn(cond,p,r) ((void)0)
+#define p_SetRingOfLm(p, r)          ((void)0)
+#define p_SetRingOfLeftv(l, r)       ((void)0)
+#endif // defined(PDEBUG)
+
+#if PDEBUG >= 1
+#define pAssume1             pAssume
+#define pPolyAssume1         pPolyAssume
+#define _pPolyAssume1        _pPolyAssume
+#define pAssumeReturn1       pAssumeReturn
+#define pPolyAssumeReturn1   pPolyAssumeReturn
+#define _pPolyAssumeReturn1  _pPolyAssumeReturn
+#define p_LmCheckPolyRing1    p_LmCheckPolyRing
+#define p_CheckRing1        p_CheckRing
+#define pIfThen1          pIfThen
+#else
+#define pAssume1(cond)               ((void)0)
+#define pPolyAssume1(cond)           ((void)0)
+#define _pPolyAssume1(cond,p,r)      ((void)0)
+#define pAssumeReturn1(cond)         ((void)0)
+#define pPolyAssumeReturn1(cond)     ((void)0)
+#define _pPolyAssumeReturn1(cond,p,r)((void)0)
+#define p_LmCheckPolyRing1(p,r)       ((void)0)
+#define p_CheckRing1(r)             ((void)0)
+#define pIfThen1(cond, check)     ((void)0)
+#endif // PDEBUG >= 1
+
+#if PDEBUG >= 2
+#define pAssume2             pAssume
+#define pPolyAssume2         pPolyAssume
+#define _pPolyAssume2        _pPolyAssume
+#define pAssumeReturn2       pAssumeReturn
+#define pPolyAssumeReturn2   pPolyAssumeReturn
+#define _pPolyAssumeReturn2  _pPolyAssumeReturn
+#define p_LmCheckPolyRing2    p_LmCheckPolyRing
+#define p_CheckRing2        p_CheckRing
+#define pIfThen2          pIfThen
+#else
+#define pAssume2(cond)               ((void)0)
+#define pPolyAssume2(cond)           ((void)0)
+#define _pPolyAssume2(cond,p,r)      ((void)0)
+#define pAssumeReturn2(cond)         ((void)0)
+#define pPolyAssumeReturn2(cond)     ((void)0)
+#define _pPolyAssumeReturn2(cond,p,r)((void)0)
+#define p_LmCheckPolyRing2(p,r)       ((void)0)
+#define p_CheckRing2(r)             ((void)0)
+#define pIfThen2(cond, check)     ((void)0)
+#endif // PDEBUG >= 2
+
+/***************************************************************
+ *
+ * Macros for access/iteration
+ *
+ ***************************************************************/
+#define _pNext(p)           ((p)->next)
+#define _pIter(p)           ((p) = (p)->next)
+
+// coeff
+#define _pGetCoeff(p)       ((p)->coef)
+#define _pSetCoeff0(p,n)    (p)->coef=n
+#define __p_GetComp(p, r)   (p)->exp[r->pCompIndex]
+#define _p_GetComp(p, r)    ((long) (r->pCompIndex >= 0 ? __p_GetComp(p, r) : 0))
+
+/***************************************************************
+ *
+ * Macros for low-level allocation
+ *
+ ***************************************************************/
+#ifdef PDEBUG
+#define p_AllocBin(p, bin, r)                   \
+do                                              \
+{                                               \
+  omTypeAllocBin(poly, p, bin);                 \
+  p_SetRingOfLm(p, r);                        \
+}                                               \
+while (0)
+#define p_FreeBinAddr(p, r) p_LmFree(p, r)
+#else
+#define p_AllocBin(p, bin, r)   omTypeAllocBin(poly, p, bin)
+#define p_FreeBinAddr(p, r)     omFreeBinAddr(p)
+#endif
+
+/***************************************************************
+ *
+ * Misc macros
+ *
+ ***************************************************************/
+#define rRing_has_Comp(r)   (r->pCompIndex >= 0)
+
+// number of Variables
+extern int pVariables;
+
+#endif // POLYS_IMPL_H
Index: kernel/polys.cc
===================================================================
--- kernel/polys.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/polys.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,926 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: polys.cc,v 1.1.1.1 2003-10-06 12:15:55 Singular Exp $ */
+
+/*
+* ABSTRACT - all basic methods to manipulate polynomials
+*/
+
+/* includes */
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "mod2.h"
+#include "structs.h"
+#include "omalloc.h"
+#include "febase.h"
+#include "numbers.h"
+#include "polys.h"
+#include "ring.h"
+
+/* ----------- global variables, set by pSetGlobals --------------------- */
+/* computes length and maximal degree of a POLYnomial */
+pLDegProc pLDeg;
+/* computes the degree of the initial term, used for std */
+pFDegProc pFDeg;
+/* the monomial ordering of the head monomials a and b */
+/* returns -1 if a comes before b, 0 if a=b, 1 otherwise */
+
+int pVariables;     // number of variables
+
+/* 1 for polynomial ring, -1 otherwise */
+int     pOrdSgn;
+// it is of type int, not BOOLEAN because it is also in ip
+/* TRUE if the monomial ordering is not compatible with pFDeg */
+BOOLEAN pLexOrder;
+
+/* ----------- global variables, set by procedures from hecke/kstd1 ----- */
+/* the highest monomial below pHEdge */
+poly      ppNoether = NULL;
+
+/* -------------------------------------------------------- */
+/*2
+* change all global variables to fit the description of the new ring
+*/
+
+
+void pSetGlobals(ring r, BOOLEAN complete)
+{
+  int i;
+  if (ppNoether!=NULL) pDelete(&ppNoether);
+  pVariables = r->N;
+  pOrdSgn = r->OrdSgn;
+  pFDeg=r->pFDeg;
+  pLDeg=r->pLDeg;
+  pLexOrder=r->LexOrder;
+
+  if (complete)
+  {
+    test &= ~ TEST_RINGDEP_OPTS;
+    test |= r->options;
+  }
+}
+
+// resets the pFDeg and pLDeg: if pLDeg is not given, it is
+// set to currRing->pLDegOrig, i.e. to the respective LDegProc which
+// only uses pFDeg (and not pDeg, or pTotalDegree, etc)
+void pSetDegProcs(pFDegProc new_FDeg, pLDegProc new_lDeg)
+{
+  assume(new_FDeg != NULL);
+  pFDeg = new_FDeg;
+  currRing->pFDeg = new_FDeg;
+
+  if (new_lDeg == NULL)
+    new_lDeg = currRing->pLDegOrig;
+
+  pLDeg = new_lDeg;
+  currRing->pLDeg = new_lDeg;
+}
+
+
+// restores pFDeg and pLDeg:
+extern void pRestoreDegProcs(pFDegProc old_FDeg, pLDegProc old_lDeg)
+{
+  assume(old_FDeg != NULL && old_lDeg != NULL);
+  pFDeg = old_FDeg;
+  currRing->pFDeg = old_FDeg;
+  pLDeg = old_lDeg;
+  currRing->pLDeg = old_lDeg;
+}
+
+/*2
+* assumes that the head term of b is a multiple of the head term of a
+* and return the multiplicant *m
+*/
+poly pDivide(poly a, poly b)
+{
+  int i;
+  poly result = pInit();
+
+  for(i=(int)pVariables; i; i--)
+    pSetExp(result,i, pGetExp(a,i)- pGetExp(b,i));
+  pSetComp(result, pGetComp(a) - pGetComp(b));
+  pSetm(result);
+  return result;
+}
+
+/*2
+* divides a by the monomial b, ignores monomials which are not divisible
+* assumes that b is not NULL
+*/
+poly pDivideM(poly a, poly b)
+{
+  if (a==NULL) return NULL;
+  poly result=a;
+  poly prev=NULL;
+  int i;
+  number inv=nInvers(pGetCoeff(b));
+
+  while (a!=NULL)
+  {
+    if (pDivisibleBy(b,a))
+    {
+      for(i=(int)pVariables; i; i--)
+         pSubExp(a,i, pGetExp(b,i));
+      pSubComp(a, pGetComp(b));
+      pSetm(a);
+      prev=a;
+      pIter(a);
+    }
+    else
+    {
+      if (prev==NULL)
+      {
+        pDeleteLm(&result);
+        a=result;
+      }
+      else
+      {
+        pDeleteLm(&pNext(prev));
+        a=pNext(prev);
+      }
+    }
+  }
+  pMult_nn(result,inv);
+  nDelete(&inv);
+  pDelete(&b);
+  return result;
+}
+
+/*2
+* returns the LCM of the head terms of a and b in *m
+*/
+void pLcm(poly a, poly b, poly m)
+{
+  int i;
+  for (i=pVariables; i; i--)
+  {
+    pSetExp(m,i, si_max( pGetExp(a,i), pGetExp(b,i)));
+  }
+  pSetComp(m, si_max(pGetComp(a), pGetComp(b)));
+  /* Don't do a pSetm here, otherwise hres/lres chockes */
+}
+
+/*2
+* convert monomial given as string to poly, e.g. 1x3y5z
+*/
+char * p_Read(char *st, poly &rc, ring r)
+{
+  if (r==NULL) { rc=NULL;return st;}
+  int i,j;
+  rc = p_Init(r);
+  char *s = r->cf->nRead(st,&(rc->coef));
+  if (s==st)
+  /* i.e. it does not start with a coeff: test if it is a ringvar*/
+  {
+    j = r_IsRingVar(s,r);
+    if (j >= 0)
+    {
+      p_IncrExp(rc,1+j,r);
+      while (*s!='\0') s++;
+      goto done;
+    }
+  }
+  while (*s!='\0')
+  {
+    char ss[2];
+    ss[0] = *s++;
+    ss[1] = '\0';
+    j = r_IsRingVar(ss,r);
+    if (j >= 0)
+    {
+      s = eati(s,&i);
+      p_AddExp(rc,1+j, (Exponent_t)i, r);
+    }
+    else
+    {
+      s--;
+      return s;
+    }
+  }
+done:
+  if (r->cf->nIsZero(pGetCoeff(rc))) p_DeleteLm(&rc,r);
+  else
+  {
+    p_Setm(rc,r);
+  }
+  return s;
+}
+
+poly pmInit(char *st, BOOLEAN &ok)
+{
+  poly p;
+  char *s=p_Read(st,p,currRing);
+  if (*s!='\0')
+  {
+    if ((s!=st)&&isdigit(st[0]))
+    {
+      errorreported=TRUE;
+    }
+    ok=FALSE;
+    pDelete(&p);
+    return NULL;
+  }
+  ok=!errorreported;
+  return p;
+}
+
+/*2
+*make p homogeneous by multiplying the monomials by powers of x_varnum
+*/
+poly pHomogen (poly p, int varnum)
+{
+  poly q=NULL, qn;
+  int  o,ii;
+  sBucket_pt bp;
+
+  if (p!=NULL)
+  {
+    if ((varnum < 1) || (varnum > pVariables))
+    {
+      return NULL;
+    }
+    o=pWTotaldegree(p);
+    q=pNext(p);
+    while (q != NULL)
+    {
+      ii=pWTotaldegree(q);
+      if (ii>o) o=ii;
+      pIter(q);
+    }
+    q = pCopy(p);
+    bp = sBucketCreate(currRing);
+    while (q != NULL)
+    {
+      ii = o-pWTotaldegree(q);
+      if (ii!=0)
+      {
+        pAddExp(q,varnum, (Exponent_t)ii);
+        pSetm(q);
+      }
+      qn = pNext(q);
+      pNext(q) = NULL;
+      sBucket_Add_p(bp, q, 1);
+      q = qn;
+    }
+    sBucketDestroyAdd(bp, &q, &ii);
+  }
+  return q;
+}
+
+/*2
+*replaces the maximal powers of the leading monomial of p2 in p1 by
+*the same powers of n, utility for dehomogenization
+*/
+poly pDehomogen (poly p1,poly p2,number n)
+{
+  polyset P;
+  int     SizeOfSet=5;
+  int     i;
+  poly    p;
+  number  nn;
+
+  P = (polyset)omAlloc0(5*sizeof(poly));
+  //for (i=0; i<5; i++)
+  //{
+  //  P[i] = NULL;
+  //}
+  pCancelPolyByMonom(p1,p2,&P,&SizeOfSet);
+  p = P[0];
+  //P[0] = NULL ;// for safety, may be removed later
+  for (i=1; i<SizeOfSet; i++)
+  {
+    if (P[i] != NULL)
+    {
+      nPower(n,i,&nn);
+      pMult_nn(P[i],nn);
+      p = pAdd(p,P[i]);
+      //P[i] =NULL; // for safety, may be removed later
+      nDelete(&nn);
+    }
+  }
+  omFreeSize((ADDRESS)P,SizeOfSet*sizeof(poly));
+  return p;
+}
+
+/*4
+*Returns the exponent of the maximal power of the leading monomial of
+*p2 in that of p1
+*/
+static int pGetMaxPower (poly p1,poly p2)
+{
+  int     i,k,res = 32000; /*a very large integer*/
+
+  if (p1 == NULL) return 0;
+  for (i=1; i<=pVariables; i++)
+  {
+    if ( pGetExp(p2,i) != 0)
+    {
+      k =  pGetExp(p1,i) /  pGetExp(p2,i);
+      if (k < res) res = k;
+    }
+  }
+  return res;
+}
+
+/*2
+*Returns as i-th entry of P the coefficient of the (i-1) power of
+*the leading monomial of p2 in p1
+*/
+void pCancelPolyByMonom (poly p1,poly p2,polyset * P,int * SizeOfSet)
+{
+  int   maxPow;
+  poly  p,qp,Coeff;
+
+  if (*P == NULL)
+  {
+    *P = (polyset) omAlloc(5*sizeof(poly));
+    *SizeOfSet = 5;
+  }
+  p = pCopy(p1);
+  while (p != NULL)
+  {
+    qp = p->next;
+    p->next = NULL;
+    maxPow = pGetMaxPower(p,p2);
+    Coeff = pDivByMonom(p,p2);
+    if (maxPow > *SizeOfSet)
+    {
+      pEnlargeSet(P,*SizeOfSet,maxPow+1-*SizeOfSet);
+      *SizeOfSet = maxPow+1;
+    }
+    (*P)[maxPow] = pAdd((*P)[maxPow],Coeff);
+    pDelete(&p);
+    p = qp;
+  }
+}
+
+/*2
+*returns the leading monomial of p1 divided by the maximal power of that
+*of p2
+*/
+poly pDivByMonom (poly p1,poly p2)
+{
+  int     k, i;
+
+  if (p1 == NULL) return NULL;
+  k = pGetMaxPower(p1,p2);
+  if (k == 0)
+    return pHead(p1);
+  else
+  {
+    number n;
+    poly p = pInit();
+
+    p->next = NULL;
+    for (i=1; i<=pVariables; i++)
+    {
+       pSetExp(p,i, pGetExp(p1,i)-k* pGetExp(p2,i));
+    }
+    nPower(p2->coef,k,&n);
+    pSetCoeff0(p,nDiv(p1->coef,n));
+    nDelete(&n);
+    pSetm(p);
+    return p;
+  }
+}
+/*----------utilities for syzygies--------------*/
+poly pTakeOutComp(poly * p, int k)
+{
+  poly q = *p,qq=NULL,result = NULL;
+
+  if (q==NULL) return NULL;
+  if (pGetComp(q)==k)
+  {
+    result = q;
+    while ((q!=NULL) && (pGetComp(q)==k))
+    {
+      pSetComp(q,0);
+      pSetmComp(q);
+      qq = q;
+      pIter(q);
+    }
+    *p = q;
+    pNext(qq) = NULL;
+  }
+  if (q==NULL) return result;
+  if (pGetComp(q) > k)
+  {
+    pDecrComp(q);
+    pSetmComp(q);
+  }
+  poly pNext_q;
+  while ((pNext_q=pNext(q))!=NULL)
+  {
+    if (pGetComp(pNext_q)==k)
+    {
+      if (result==NULL)
+      {
+        result = pNext_q;
+        qq = result;
+      }
+      else
+      {
+        pNext(qq) = pNext_q;
+        pIter(qq);
+      }
+      pNext(q) = pNext(pNext_q);
+      pNext(qq) =NULL;
+      pSetComp(qq,0);
+      pSetmComp(qq);
+    }
+    else
+    {
+      /*pIter(q);*/ q=pNext_q;
+      if (pGetComp(q) > k)
+      {
+        pDecrComp(q);
+        pSetmComp(q);
+      }
+    }
+  }
+  return result;
+}
+
+// Splits *p into two polys: *q which consists of all monoms with
+// component == comp and *p of all other monoms *lq == pLength(*q)
+void pTakeOutComp(poly *r_p, Exponent_t comp, poly *r_q, int *lq)
+{
+  spolyrec pp, qq;
+  poly p, q, p_prev;
+  int l = 0;
+
+#ifdef HAVE_ASSUME
+  int lp = pLength(*r_p);
+#endif
+
+  pNext(&pp) = *r_p;
+  p = *r_p;
+  p_prev = &pp;
+  q = &qq;
+
+  while(p != NULL)
+  {
+    while (pGetComp(p) == comp)
+    {
+      pNext(q) = p;
+      pIter(q);
+      pSetComp(p, 0);
+      pSetmComp(p);
+      pIter(p);
+      l++;
+      if (p == NULL)
+      {
+        pNext(p_prev) = NULL;
+        goto Finish;
+      }
+    }
+    pNext(p_prev) = p;
+    p_prev = p;
+    pIter(p);
+  }
+
+  Finish:
+  pNext(q) = NULL;
+  *r_p = pNext(&pp);
+  *r_q = pNext(&qq);
+  *lq = l;
+#ifdef HAVE_ASSUME
+  assume(pLength(*r_p) + pLength(*r_q) == lp);
+#endif
+  pTest(*r_p);
+  pTest(*r_q);
+}
+
+void pDecrOrdTakeOutComp(poly *r_p, Exponent_t comp, Order_t order,
+                         poly *r_q, int *lq)
+{
+  spolyrec pp, qq;
+  poly p, q, p_prev;
+  int l = 0;
+
+  pNext(&pp) = *r_p;
+  p = *r_p;
+  p_prev = &pp;
+  q = &qq;
+
+#ifdef HAVE_ASSUME
+  if (p != NULL)
+  {
+    while (pNext(p) != NULL)
+    {
+      assume(pGetOrder(p) >= pGetOrder(pNext(p)));
+      pIter(p);
+    }
+  }
+  p = *r_p;
+#endif
+
+  while (p != NULL && pGetOrder(p) > order) pIter(p);
+
+  while(p != NULL && pGetOrder(p) == order)
+  {
+    while (pGetComp(p) == comp)
+    {
+      pNext(q) = p;
+      pIter(q);
+      pIter(p);
+      pSetComp(p, 0);
+      pSetmComp(p);
+      l++;
+      if (p == NULL || pGetOrder(p) != order)
+      {
+        pNext(p_prev) = p;
+        goto Finish;
+      }
+    }
+    pNext(p_prev) = p;
+    p_prev = p;
+    pIter(p);
+  }
+
+  Finish:
+  pNext(q) = NULL;
+  *r_p = pNext(&pp);
+  *r_q = pNext(&qq);
+  *lq = l;
+}
+
+#if 1
+poly pTakeOutComp1(poly * p, int k)
+{
+  poly q = *p;
+
+  if (q==NULL) return NULL;
+
+  poly qq=NULL,result = NULL;
+
+  if (pGetComp(q)==k)
+  {
+    result = q; /* *p */
+    while ((q!=NULL) && (pGetComp(q)==k))
+    {
+      pSetComp(q,0);
+      pSetmComp(q);
+      qq = q;
+      pIter(q);
+    }
+    *p = q;
+    pNext(qq) = NULL;
+  }
+  if (q==NULL) return result;
+//  if (pGetComp(q) > k) pGetComp(q)--;
+  while (pNext(q)!=NULL)
+  {
+    if (pGetComp(pNext(q))==k)
+    {
+      if (result==NULL)
+      {
+        result = pNext(q);
+        qq = result;
+      }
+      else
+      {
+        pNext(qq) = pNext(q);
+        pIter(qq);
+      }
+      pNext(q) = pNext(pNext(q));
+      pNext(qq) =NULL;
+      pSetComp(qq,0);
+      pSetmComp(qq);
+    }
+    else
+    {
+      pIter(q);
+//      if (pGetComp(q) > k) pGetComp(q)--;
+    }
+  }
+  return result;
+}
+#endif
+
+void pDeleteComp(poly * p,int k)
+{
+  poly q;
+
+  while ((*p!=NULL) && (pGetComp(*p)==k)) pDeleteLm(p);
+  if (*p==NULL) return;
+  q = *p;
+  if (pGetComp(q)>k)
+  {
+    pDecrComp(q);
+    pSetmComp(q);
+  }
+  while (pNext(q)!=NULL)
+  {
+    if (pGetComp(pNext(q))==k)
+      pDeleteLm(&(pNext(q)));
+    else
+    {
+      pIter(q);
+      if (pGetComp(q)>k)
+      {
+        pDecrComp(q);
+        pSetmComp(q);
+      }
+    }
+  }
+}
+/*----------end of utilities for syzygies--------------*/
+
+/*2
+* pair has no common factor ? or is no polynomial
+*/
+BOOLEAN pHasNotCF(poly p1, poly p2)
+{
+
+  if (pGetComp(p1) > 0 || pGetComp(p2) > 0)
+    return FALSE;
+  int i = 1;
+  loop
+  {
+    if ((pGetExp(p1, i) > 0) && (pGetExp(p2, i) > 0))   return FALSE;
+    if (i == pVariables)                                return TRUE;
+    i++;
+  }
+}
+
+
+/*2
+*divides p1 by its leading coefficient
+*/
+void pNorm(poly p1)
+{
+  poly h;
+  number k, c;
+
+  if (p1!=NULL)
+  {
+    if (!nIsOne(pGetCoeff(p1)))
+    {
+      nNormalize(pGetCoeff(p1));
+      k=pGetCoeff(p1);
+      c = nInit(1);
+      pSetCoeff0(p1,c);
+      h = pNext(p1);
+      while (h!=NULL)
+      {
+        c=nDiv(pGetCoeff(h),k);
+        if (!nIsOne(c)) nNormalize(c);
+        pSetCoeff(h,c);
+        pIter(h);
+      }
+      nDelete(&k);
+    }
+    else
+    {
+      if (nNormalize != nDummy2)
+      {
+        h = pNext(p1);
+        while (h!=NULL)
+        {
+          nNormalize(pGetCoeff(h));
+          pIter(h);
+        }
+      }
+    }
+  }
+}
+
+/*2
+*normalize all coefficients
+*/
+void p_Normalize(poly p, ring r) 
+{
+  if (rField_has_simple_inverse(r)) return; /* Z/p, GF(p,n), R, long R/C */
+  while (p!=NULL)
+  {
+    if (currRing==r) {nTest(pGetCoeff(p));}
+    n_Normalize(pGetCoeff(p),r);
+    pIter(p);
+  }
+}
+
+// splits p into polys with Exp(n) == 0 and Exp(n) != 0
+// Poly with Exp(n) != 0 is reversed
+static void pSplitAndReversePoly(poly p, int n, poly *non_zero, poly *zero)
+{
+  if (p == NULL)
+  {
+    *non_zero = NULL;
+    *zero = NULL;
+    return;
+  }
+  spolyrec sz;
+  poly z, n_z, next;
+  z = &sz;
+  n_z = NULL;
+
+  while(p != NULL)
+  {
+    next = pNext(p);
+    if (pGetExp(p, n) == 0)
+    {
+      pNext(z) = p;
+      pIter(z);
+    }
+    else
+    {
+      pNext(p) = n_z;
+      n_z = p;
+    }
+    p = next;
+  }
+  pNext(z) = NULL;
+  *zero = pNext(&sz);
+  *non_zero = n_z;
+  return;
+}
+
+/*3
+* substitute the n-th variable by 1 in p
+* destroy p
+*/
+static poly pSubst1 (poly p,int n)
+{
+  poly qq,result = NULL;
+  poly zero, non_zero;
+
+  // reverse, so that add is likely to be linear
+  pSplitAndReversePoly(p, n, &non_zero, &zero);
+
+  while (non_zero != NULL)
+  {
+    assume(pGetExp(non_zero, n) != 0);
+    qq = non_zero;
+    pIter(non_zero);
+    qq->next = NULL;
+    pSetExp(qq,n,0);
+    pSetm(qq);
+    result = pAdd(result,qq);
+  }
+  p = pAdd(result, zero);
+  pTest(p);
+  return p;
+}
+
+/*3
+* substitute the n-th variable by number e in p
+* destroy p
+*/
+static poly pSubst2 (poly p,int n, number e)
+{
+  assume( ! nIsZero(e) );
+  poly qq,result = NULL;
+  number nn, nm;
+  poly zero, non_zero;
+
+  // reverse, so that add is likely to be linear
+  pSplitAndReversePoly(p, n, &non_zero, &zero);
+
+  while (non_zero != NULL)
+  {
+    assume(pGetExp(non_zero, n) != 0);
+    qq = non_zero;
+    pIter(non_zero);
+    qq->next = NULL;
+    nPower(e, pGetExp(qq, n), &nn);
+    nm = nMult(nn, pGetCoeff(qq));
+    pSetCoeff(qq, nm);
+    nDelete(&nn);
+    pSetExp(qq, n, 0);
+    pSetm(qq);
+    result = pAdd(result,qq);
+  }
+  p = pAdd(result, zero);
+  pTest(p);
+  return p;
+}
+
+
+/* delete monoms whose n-th exponent is different from zero */
+poly pSubst0(poly p, int n)
+{
+  spolyrec res;
+  poly h = &res;
+  pNext(h) = p;
+
+  while (pNext(h)!=NULL)
+  {
+    if (pGetExp(pNext(h),n)!=0)
+    {
+      pDeleteLm(&pNext(h));
+    }
+    else
+    {
+      pIter(h);
+    }
+  }
+  pTest(pNext(&res));
+  return pNext(&res);
+}
+
+/*2
+* substitute the n-th variable by e in p
+* destroy p
+*/
+poly pSubst(poly p, int n, poly e)
+{
+  if (e == NULL) return pSubst0(p, n);
+
+  if (pIsConstant(e))
+  {
+    if (nIsOne(pGetCoeff(e))) return pSubst1(p,n);
+    else return pSubst2(p, n, pGetCoeff(e));
+  }
+
+  int exponent,i;
+  poly h, res, m;
+  int *me,*ee;
+  number nu,nu1;
+
+  me=(int *)omAlloc((pVariables+1)*sizeof(int));
+  ee=(int *)omAlloc((pVariables+1)*sizeof(int));
+  if (e!=NULL) pGetExpV(e,ee);
+  res=NULL;
+  h=p;
+  while (h!=NULL)
+  {
+    if ((e!=NULL) || (pGetExp(h,n)==0))
+    {
+      m=pHead(h);
+      pGetExpV(m,me);
+      exponent=me[n];
+      me[n]=0;
+      for(i=pVariables;i>0;i--)
+        me[i]+=exponent*ee[i];
+      pSetExpV(m,me);
+      if (e!=NULL)
+      {
+        nPower(pGetCoeff(e),exponent,&nu);
+        nu1=nMult(pGetCoeff(m),nu);
+        nDelete(&nu);
+        pSetCoeff(m,nu1);
+      }
+      res=pAdd(res,m);
+    }
+    pDeleteLm(&h);
+  }
+  omFreeSize((ADDRESS)me,(pVariables+1)*sizeof(int));
+  omFreeSize((ADDRESS)ee,(pVariables+1)*sizeof(int));
+  return res;
+}
+
+BOOLEAN pCompareChain (poly p,poly p1,poly p2,poly lcm)
+{
+  int k, j;
+
+  if (lcm==NULL) return FALSE;
+
+  for (j=pVariables; j; j--)
+    if ( pGetExp(p,j) >  pGetExp(lcm,j)) return FALSE;
+  if ( pGetComp(p) !=  pGetComp(lcm)) return FALSE;
+  for (j=pVariables; j; j--)
+  {
+    if (pGetExp(p1,j)!=pGetExp(lcm,j))
+    {
+      if (pGetExp(p,j)!=pGetExp(lcm,j))
+      {
+        for (k=pVariables; k>j; k--)
+        {
+          if ((pGetExp(p,k)!=pGetExp(lcm,k))
+          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
+            return TRUE;
+        }
+        for (k=j-1; k; k--)
+        {
+          if ((pGetExp(p,k)!=pGetExp(lcm,k))
+          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
+            return TRUE;
+        }
+        return FALSE;
+      }
+    }
+    else if (pGetExp(p2,j)!=pGetExp(lcm,j))
+    {
+      if (pGetExp(p,j)!=pGetExp(lcm,j))
+      {
+        for (k=pVariables; k>j; k--)
+        {
+          if ((pGetExp(p,k)!=pGetExp(lcm,k))
+          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
+            return TRUE;
+        }
+        for (k=j-1; k!=0 ; k--)
+        {
+          if ((pGetExp(p,k)!=pGetExp(lcm,k))
+          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
+            return TRUE;
+        }
+        return FALSE;
+      }
+    }
+  }
+  return FALSE;
+}
Index: kernel/polys.h
===================================================================
--- kernel/polys.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/polys.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,441 @@
+#ifndef POLYS_H
+#define POLYS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: polys.h,v 1.1.1.1 2003-10-06 12:16:01 Singular Exp $ */
+/*
+* ABSTRACT - all basic methods to manipulate polynomials of the
+             currRing
+*/
+
+#include "p_polys.h"
+/*
+ Some general remarks:
+ We divide poly operations into roughly 4 categories:
+ Level 2: operations on monomials/polynomials with constant time,
+          or operations which are just dispatchers to other
+          poly routines
+          - implemented in: pInline2.h
+          - debugging only if PDEBUG >= 2
+          - normally inlined, unless PDEBUG >= 2 || NO_INLINE2
+ Level 1: operations on monomials with time proportional to length
+          - implemented in: pInline1.h
+          - debugging only if PDEBUG >= 1
+          - normally inlined, unless PDEBUG >= 1 || NO_INLINE1
+ Level 0: short operations on polynomials with time proportional to
+          length of poly
+          - implemented in pInline0.cc
+          - debugging if PDEBUG
+          - normally _not_ inlined: can be forced with
+            #define DO_PINLINE0
+            #include "pInline0.h"
+ Misc   : operations on polynomials which do not fit in any of the
+          above categories
+          - implemented in: polys*.cc
+          - never inlined
+          - debugging if PDEBUG >= 0
+
+ You can set PDEBUG on a per-file basis, before including "mod2.h" like
+   #define PDEBUG 2
+   #include "mod2.h"
+ However, PDEBUG will only be in effect, if !NDEBUG.
+
+ All p_* operations take as last argument a ring
+ and are ring independent. Their corresponding p* operations are usually
+ just macros to the respective p_*(..,currRing).
+
+*/
+
+/***************************************************************
+ *
+ * Primitives for accessing and setting fields of a poly
+ * poly must be != NULL
+ *
+ ***************************************************************/
+// deletes old coeff before setting the new one
+#define pSetCoeff(p,n)      p_SetCoeff(p,n,currRing)
+
+// Order
+#define pGetOrder(p)        p_GetOrder(p, currRing)
+// don't use this
+#define pSetOrder(p, o)     p_SetOrder(p, o, currRing)
+
+// Component
+#define pGetComp(p)         _p_GetComp(p, currRing)
+#define pSetComp(p,v)       p_SetComp(p,v, currRing)
+#define pIncrComp(p)        p_IncrComp(p,currRing)
+#define pDecrComp(p)        p_DecrComp(p,currRing)
+#define pAddComp(p,v)       p_AddComp(p,v,currRing)
+#define pSubComp(p,v)       p_SubComp(p,v,currRing)
+
+// Exponent
+#define pGetExp(p,i)        p_GetExp(p, i, currRing)
+#define pSetExp(p,i,v)      p_SetExp(p, i, v, currRing)
+#define pIncrExp(p,i)       p_IncrExp(p,i, currRing)
+#define pDecrExp(p,i)       p_DecrExp(p,i, currRing)
+#define pAddExp(p,i,v)      p_AddExp(p,i,v, currRing)
+#define pSubExp(p,i,v)      p_SubExp(p,i,v, currRing)
+#define pMultExp(p,i,v)     p_MultExp(p,i,v, currRing)
+#define pGetExpSum(p1, p2, i)    p_GetExpSum(p1, p2, i, currRing)
+#define pGetExpDiff(p1, p2, i)   p_GetExpDiff(p1, p2, i, currRing)
+
+/***************************************************************
+ *
+ * Allocation/Initalization/Deletion
+ * except for pDeleteLm and pHead, all polys must be != NULL
+ *
+ ***************************************************************/
+// allocates the space for a new monomial -- no initialization !!!
+#define pNew()          p_New(currRing)
+// allocates a new monomial and initializes everything to 0
+#define pInit()         p_Init(currRing)
+// like pInit, except that expvector is initialized to that of p,
+// p must be != NULL
+#define pLmInit(p)  p_LmInit(p, currRing)
+// returns newly allocated copy of Lm(p), coef is copied, next=NULL,
+// p might be NULL
+#define pHead(p)        p_Head(p, currRing)
+// if *p_ptr != NULL, delete p_ptr->coef, *p_ptr, and set *p_ptr to
+// pNext(*p_ptr)
+static inline void pDeleteLm(poly *p) {p_DeleteLm(p, currRing);}
+// if (p!=NULL) delete p-coef and p
+static inline void pDeleteLm(poly p)  {p_DeleteLm(p, currRing);}
+// frees the space of the monomial m, assumes m != NULL
+// coef is not freed, m is not advanced
+static inline void pLmFree(poly p)    {p_LmFree(p, currRing);}
+// like pLmFree, but advances p
+static inline void pLmFree(poly *p)   {p_LmFree(p, currRing);}
+// assumes p != NULL, deletes p, returns pNext(p)
+#define pLmFreeAndNext(p) p_LmFreeAndNext(p, currRing)
+// assume p != NULL, deletes Lm(p)->coef and Lm(p)
+#define pLmDelete(p)    p_LmDelete(p, currRing)
+// like pLmDelete, returns pNext(p)
+#define pLmDeleteAndNext(p) p_LmDeleteAndNext(p, currRing)
+// used by iparith.cc
+extern poly pHeadProc(poly p);
+
+/***************************************************************
+ *
+ * Operation on ExpVectors: assumes polys != NULL
+ *
+ ***************************************************************/
+
+#define pExpVectorCopy(d_p, s_p)    p_ExpVectorCopy(d_p, s_p, currRing)
+#define pExpVectorAdd(p1, p2)       p_ExpVectorAdd(p1, p2, currRing)
+#define pExpVectorSub(p1, p2)       p_ExpVectorSub(p1, p2, currRing)
+#define pExpVectorAddSub(p1, p2, p3)p_ExpVectorAddSub(p1, p2, p3, currRing)
+#define pExpVectorSum(pr, p1, p2)   p_ExpVectorSum(pr, p1, p2, currRing)
+#define pExpVectorDiff(pr, p1, p2)  p_ExpVectorDiff(pr, p1, p2, currRing)
+#define pExpVectorEqual(p1, p2)     p_ExpVectorEqual(p1, p2, currRing)
+#define pExpVectorQuerSum(p)        p_ExpVectorQuerSum(p, currRing)
+
+// Gets a copy of (resp. set) the exponent vector, where e is assumed
+// to point to (r->N +1)*sizeof(Exponent_t) memory. Exponents are
+// filled in as follows: comp, e_1, .., e_n
+#define pGetExpV(p, e)      p_GetExpV(p, e, currRing)
+#define pSetExpV(p, e)      p_SetExpV(p, e, currRing)
+
+/***************************************************************
+ *
+ * Comparisons: they are all done without regarding coeffs
+ *
+ ***************************************************************/
+// returns 0|1|-1 if p=q|p>q|p<q w.r.t monomial ordering
+#define pLmCmp(p,q)         p_LmCmp(p,q,currRing)
+// executes axtionE|actionG|actionS if p=q|p>q|p<q w.r.t monomial ordering
+// action should be a "goto ..."
+#define pLmCmpAction(p,q, actionE, actionG, actionS)  \
+  _p_LmCmpAction(p,q,currRing, actionE, actionG,actionS)
+
+#define pLmEqual(p1, p2)     pExpVectorEqual(p1, p2)
+
+// pCmp: args may be NULL
+// returns: (p2==NULL ? 1 : (p1 == NULL ? -1 : p_LmCmp(p1, p2)))
+#define pCmp(p1, p2)    p_Cmp(p1, p2, currRing)
+
+
+/***************************************************************
+ *
+ * Divisiblity tests, args must be != NULL, except for
+ * pDivisbleBy
+ *
+ ***************************************************************/
+// returns TRUE, if leading monom of a divides leading monom of b
+// i.e., if there exists a expvector c > 0, s.t. b = a + c;
+#define pDivisibleBy(a, b)  p_DivisibleBy(a,b,currRing)
+// like pDivisibleBy, except that it is assumed that a!=NULL, b!=NULL
+#define pLmDivisibleBy(a,b)  p_LmDivisibleBy(a,b,currRing)
+// like pLmDivisibleBy, does not check components
+#define pLmDivisibleByNoComp(a, b) p_LmDivisibleByNoComp(a,b,currRing)
+// Divisibility tests based on Short Exponent vectors
+// sev_a     == pGetShortExpVector(a)
+// not_sev_b == ~ pGetShortExpVector(b)
+#define pLmShortDivisibleBy(a, sev_a, b, not_sev_b) \
+  p_LmShortDivisibleBy(a, sev_a, b, not_sev_b, currRing)
+// returns the "Short Exponent Vector" -- used to speed up divisibility
+// tests (see polys-impl.cc )
+#define pGetShortExpVector(a)   p_GetShortExpVector(a, currRing)
+
+/***************************************************************
+ *
+ * Copying/Deleteion of polys: args may be NULL
+ *
+ ***************************************************************/
+// return a copy of the poly
+#define pCopy(p) p_Copy(p, currRing)
+#define pDelete(p_ptr)  p_Delete(p_ptr, currRing)
+
+/***************************************************************
+ *
+ * Copying/Deleteion of polys: args may be NULL
+ *  - p/q as arg mean a poly
+ *  - m a monomial
+ *  - n a number
+ *  - pp (resp. qq, mm, nn) means arg is constant
+ *  - p (resp, q, m, n)     means arg is destroyed
+ *
+ ***************************************************************/
+#define pNeg(p)                     p_Neg(p, currRing)
+#define ppMult_nn(p, n)             pp_Mult_nn(p, n, currRing)
+#define pMult_nn(p, n)              p_Mult_nn(p, n, currRing)
+#define ppMult_mm(p, m)             pp_Mult_mm(p, m, currRing)
+#define pMult_mm(p, m)              p_Mult_mm(p, m, currRing)
+#define pAdd(p, q)                  p_Add_q(p, q, currRing)
+#define pMinus_mm_Mult_qq(p, m, q)  p_Minus_mm_Mult_qq(p, m, q, currRing)
+#define pPlus_mm_Mult_qq(p, m, q)   p_Plus_mm_Mult_qq(p, m, q, currRing)
+#define pMult(p, q)                 p_Mult_q(p, q, currRing)
+#define ppMult_qq(p, q)             pp_Mult_qq(p, q, currRing)
+// p*Coeff(m) for such monomials pm of p, for which m is divisble by pm
+#define ppMult_Coeff_mm_DivSelect(p, m)   pp_Mult_Coeff_mm_DivSelect(p, m, currRing)
+/*************************************************************************
+ *
+ * Sort routines
+ *
+ *************************************************************************/
+// sorts p, assumes all monomials in p are different
+#define pSortMerger(p)          pSort(p)
+#define pSort(p)                p_SortMerge(p, currRing)
+
+// sorts p, p may have equal monomials
+#define pSortAdd(p)             p_SortAdd(p, currRing)
+
+
+// Assume: If considerd only as poly in any component of p
+// (say, monomials of other components of p are set to 0),
+// then p is already sorted correctly
+#define pSortCompCorrect(p) pSort(p)
+
+/***************************************************************
+ *
+ * Predicates on polys/Lm's
+ *
+ ***************************************************************/
+// return true if all p is eihter NULL, or if all exponents
+// of p are 0 and Comp of p is zero
+#define   pIsConstantComp(p)        p_IsConstantComp(p, currRing)
+// like above, except that Comp might be != 0
+#define   pIsConstant(p)            p_IsConstant(p,currRing)
+// return true if the Lm is a constant <>0
+#define   pIsUnit(p)            p_IsUnit(p,currRing)
+// like above, except that p must be != NULL
+#define   pLmIsConstantComp(p)      p_LmIsConstantComp(p, currRing)
+#define   pLmIsConstant(p)          p_LmIsConstant(p,currRing)
+
+// return TRUE if all monomials of p are constant
+#define   pIsConstantPoly(p)        p_IsConstantPoly(p, currRing)
+
+#define   pIsPurePower(p)   p_IsPurePower(p, currRing)
+#define   pIsVector(p)      (pGetComp(p)>0)
+
+
+/***************************************************************
+ *
+ * Old stuff
+ *
+ ***************************************************************/
+
+#define pFetchCopy(r,p)     _pFetchCopy(r,p)
+// Similar to pFetchCopy, except that poly p is deleted
+#define pFetchCopyDelete(r, p) _pFetchCopyDelete(r, p)
+
+typedef poly*   polyset;
+extern int      pVariables;
+extern int      pOrdSgn;
+extern BOOLEAN  pLexOrder;
+extern poly     ppNoether;
+extern BOOLEAN  pVectorOut;
+
+/*-------------predicate on polys ----------------------*/
+BOOLEAN   pHasNotCF(poly p1, poly p2);   /*has no common factor ?*/
+void      pSplit(poly p, poly * r);   /*p => IN(p), r => REST(p) */
+
+
+
+/*-------------ring management:----------------------*/
+//extern void pChangeRing(ring newRing);
+extern void pSetGlobals(ring r, BOOLEAN complete = TRUE);
+// resets the pFDeg and pLDeg: if pLDeg is not given, it is
+// set to currRing->pLDegOrig, i.e. to the respective LDegProc which
+// only uses pFDeg (and not pDeg, or pTotalDegree, etc).
+// If you use this, make sure your procs does not make any assumptions
+// on oredering and/or OrdIndex -- otherwise they might return wrong results
+// on strat->tailRing
+extern void pSetDegProcs(pFDegProc new_FDeg, pLDegProc new_lDeg = NULL);
+// restores pFDeg and pLDeg:
+extern void pRestoreDegProcs(pFDegProc old_FDeg, pLDegProc old_lDeg);
+
+/*-----------the ordering of monomials:-------------*/
+#define pSetm(p)    p_Setm(p, currRing)
+// TODO:
+#define pSetmComp   pSetm
+
+/***************************************************************
+ *
+ * Degree stuff -- see p_polys.cc for explainations
+ *
+ ***************************************************************/
+extern pLDegProc pLDeg;
+extern pFDegProc pFDeg;
+int  pWeight(int c, ring r = currRing);
+long pDeg(poly p, ring r = currRing);
+long pTotaldegree(poly p, ring r = currRing);
+long pWTotaldegree(poly p, ring r = currRing);
+long pWDegree(poly p, ring r = currRing);
+long pLDeg0(poly p,int *l, ring r = currRing);
+long pLDeg0c(poly p,int *l, ring r = currRing);
+long pLDegb(poly p,int *l, ring r = currRing);
+long pLDeg1(poly p,int *l, ring r = currRing);
+long pLDeg1c(poly p,int *l, ring r = currRing);
+long pLDeg1_Deg(poly p,int *l, ring r = currRing);
+long pLDeg1c_Deg(poly p,int *l, ring r = currRing);
+long pLDeg1_Totaldegree(poly p,int *l, ring r = currRing);
+long pLDeg1c_Totaldegree(poly p,int *l, ring r = currRing);
+long pLDeg1_WFirstTotalDegree(poly p,int *l, ring r=currRing);
+long pLDeg1c_WFirstTotalDegree(poly p,int *l, ring r=currRing);
+
+/*-------------pComp for syzygies:-------------------*/
+
+void pSetModDeg(intvec *w);
+
+
+
+
+poly      pmInit(char *s, BOOLEAN &ok);     /* monom -> poly, interpreter */
+char *    p_Read(char *s, poly &p, ring r); /* monom -> poly */
+void      ppDelete(poly * a, ring r);
+
+/*-------------operations on polynomials:------------*/
+poly      pSub(poly a, poly b);
+poly      pPower(poly p, int i);
+
+// ----------------- define to enable new p_procs -----*/
+
+poly      pDivide(poly a, poly b);
+poly      pDivideM(poly a, poly b);
+void      pLcm(poly a, poly b, poly m);
+poly      pDiff(poly a, int k);
+poly      pDiffOp(poly a, poly b,BOOLEAN multiply);
+
+#define   pMaxComp(p)   p_MaxComp(p, currRing)
+#define   pMinComp(p)   p_MinComp(p, currRing)
+int pMaxCompProc(poly p);
+
+#define   pOneComp(p)       p_OneComp(p, currRing)
+#define   pSetCompP(a,i)    p_SetCompP(a, i, currRing)
+
+// let's inline those, so that we can call them from the debugger
+inline char*   pString(poly p)    {return p_String(p, currRing, currRing);}
+inline char*   pString0(poly p)   {return p_String0(p, currRing, currRing);}
+inline void    pWrite(poly p)     {p_Write(p, currRing, currRing);}
+inline void    pWrite0(poly p)    {p_Write0(p, currRing, currRing);}
+inline void    wrp(poly p)        {p_wrp(p, currRing, currRing);}
+
+void      pEnlargeSet(polyset *p, int length, int increment);
+#define   pISet(i) p_ISet(i,currRing)
+#define   pNSet(n) p_NSet(n,currRing)
+#define   pOne()   pISet(1)
+
+void      pContent(poly p);
+void      pCleardenom(poly p);
+void      p_Normalize(poly p, ring r);
+#define   pNormalize(p) p_Normalize(p,currRing)
+
+// homogenizes p by multiplying certain powers of the varnum-th variable
+poly      pHomogen (poly p, int varnum);
+
+// replaces the maximal powers of the leading monomial of p2 in p1 by
+// the same powers of n, utility for dehomogenization
+poly      pDehomogen (poly p1,poly p2,number n);
+BOOLEAN   pIsHomogeneous (poly p);
+
+// returns the leading monomial of p1 divided by the maximal power of
+// that of p2
+poly      pDivByMonom (poly p1,poly p2);
+
+// Returns as i-th entry of P the coefficient of the (i-1) power of
+// the leading monomial of p2 in p1
+void      pCancelPolyByMonom (poly p1,poly p2,polyset * P,int * SizeOfSet);
+
+poly      pPermPoly (poly p, int * perm, ring OldRing, nMapFunc nMap,
+                     int *par_perm=NULL, int OldPar=0);
+
+/*BOOLEAN   pVectorHasUnitM(poly p, int * k);*/
+BOOLEAN   pVectorHasUnitB(poly p, int * k);
+void      pVectorHasUnit(poly p, int * k, int * len);
+poly      pTakeOutComp1(poly * p, int k);
+// Splits *p into two polys: *q which consists of all monoms with
+// component == comp and *p of all other monoms *lq == pLength(*q)
+// On return all components pf *q == 0
+void pTakeOutComp(poly *p, Exponent_t comp, poly *q, int *lq);
+// Similar to pTakeOutComp, except that only those components are
+// taken out whose Order == order
+// ASSUME: monomial ordering is Order compatible, i.e., if m1, m2 Monoms then
+//         m1 >= m2 ==> pGetOrder(m1) >= pGetOrder(m2)
+void pDecrOrdTakeOutComp(poly *p, Exponent_t comp, Order_t order,
+                         poly *q, int *lq);
+// This is something weird -- Don't use it, unless you know what you are doing
+poly      pTakeOutComp(poly * p, int k);
+void      pSetPolyComp(poly p, int comp);
+void      pDeleteComp(poly * p,int k);
+void      pNorm(poly p);
+poly      pSubst(poly p, int n, poly e);
+poly      ppJet(poly p, int m);
+poly      pJet(poly p, int m);
+poly      ppJetW(poly p, int m, short * iv);
+poly      pJetW(poly p, int m, short * iv);
+int pMinDeg(poly p,intvec *w=NULL);
+poly      pSeries(int n,poly p,poly u=NULL,intvec *w=NULL);
+poly      pInvers(int n, poly p,intvec *w=NULL);
+// maximum weigthed degree of all monomials of p, w is indexed from
+// 1..pVariables
+long      pDegW(poly p, short *w);
+
+/*-----------type conversions ----------------------------*/
+poly  pPolys2Vec(polyset p, int len);
+void  pVec2Polys(poly v, polyset *p, int *len);
+int   pVar(poly m);
+
+/*-----------specials for spoly-computations--------------*/
+BOOLEAN pCompareChain (poly p,poly p1,poly p2,poly lcm);
+BOOLEAN pEqualPolys(poly p1,poly p2);
+BOOLEAN pComparePolys(poly p1,poly p2);
+
+
+
+/***************************************************************
+ *
+ * PDEBUG stuff
+ *
+ ***************************************************************/
+#ifdef PDEBUG
+#define pTest(p)        _p_Test(p, currRing, PDEBUG)
+#define pLmTest(p)      _p_LmTest(p, currRing, PDEBUG)
+
+#else // ! PDEBUG
+
+#define pTest(p)        ((void)0)
+#define pLmTest(p)      ((void)0)
+#endif
+
+#endif // POLYS_H
Index: kernel/polys0.cc
===================================================================
--- kernel/polys0.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/polys0.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,206 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: polys0.cc,v 1.1.1.1 2003-10-06 12:15:55 Singular Exp $ */
+
+/*
+* ABSTRACT - all basic methods to convert polynomials to strings
+*/
+
+/* includes */
+#include "mod2.h"
+#include "structs.h"
+#include "numbers.h"
+#include "ring.h"
+#include "p_polys.h"
+#include "febase.h"
+
+/*2
+* writes a monomial (p),
+* uses form x*gen(.) if ko != coloumn number of p
+*/
+static void writemon(poly p, int ko, ring r)
+{
+  BOOLEAN wroteCoef=FALSE,writeGen=FALSE;
+
+  if (pGetCoeff(p)!=NULL)
+    n_Normalize(pGetCoeff(p),r);
+
+  if (((p_GetComp(p,r) == (short)ko)
+    &&(p_LmIsConstantComp(p, r)))
+  || ((!n_IsOne(pGetCoeff(p),r))
+    && (!n_IsMOne(pGetCoeff(p),r))
+  )
+  )
+  {
+    n_Write(p->coef,r);
+    wroteCoef=(rShortOut(r) == FALSE ||(r->parameter!=NULL));
+    writeGen=TRUE;
+  }
+  else if (n_IsMOne(pGetCoeff(p),r))
+  {
+    if (n_GreaterZero(pGetCoeff(p),r))
+    {
+      n_Write(p->coef,r);
+      wroteCoef=(rShortOut(r) == FALSE ||(r->parameter!=NULL));
+      writeGen=TRUE;
+    }
+    else
+      StringAppendS("-");
+  }
+
+  int i;
+  for (i=0; i<r->N; i++)
+  {
+    {
+      Exponent_t ee = p_GetExp(p,i+1,r);
+      if (ee!=0)
+      {
+        if (wroteCoef)
+          StringAppendS("*");
+        //else
+          wroteCoef=(rShortOut(r) == FALSE);
+        writeGen=TRUE;
+        StringAppendS(rRingVar(i, r));
+        if (ee != 1)
+        {
+          if (rShortOut(r)==0) StringAppendS("^");
+          StringAppend("%d", ee);
+        }
+      }
+    }
+  }
+  //StringAppend("{%d}",p->Order);
+  if (p_GetComp(p, r) != (Exponent_t)ko)
+  {
+    if (writeGen) StringAppendS("*");
+    StringAppend("gen(%d)", p_GetComp(p, r));
+  }
+}
+
+char* p_String0(poly p, ring lmRing, ring tailRing)
+{
+  if (p == NULL)
+  {
+    return StringAppendS("0");
+  }
+  if ((p_GetComp(p, lmRing) == 0) || (!lmRing->VectorOut))
+  {
+    writemon(p,0, lmRing);
+    p = pNext(p);
+    while (p!=NULL)
+    {
+      if ((p->coef==NULL)||n_GreaterZero(p->coef,tailRing))
+        StringAppendS("+");
+      writemon(p,0, tailRing);
+      p = pNext(p);
+    }
+    return StringAppendS("");
+  }
+
+  Exponent_t k = 1;
+  StringAppendS("[");
+  loop
+  {
+    while (k < p_GetComp(p,lmRing))
+    {
+      StringAppendS("0,");
+      k++;
+    }
+    writemon(p,k,lmRing);
+    pIter(p);
+    while ((p!=NULL) && (k == p_GetComp(p, tailRing)))
+    {
+      if (n_GreaterZero(p->coef,tailRing)) StringAppendS("+");
+      writemon(p,k,tailRing);
+      pIter(p);
+    }
+    if (p == NULL) break;
+    StringAppendS(",");
+    k++;
+  }
+  return StringAppendS("]");
+}
+
+char* p_String(poly p, ring lmRing, ring tailRing)
+{
+  StringSetS("");
+  return p_String0(p, lmRing, tailRing);
+}
+
+/*2
+* writes a polynomial p to stdout
+*/
+void p_Write0(poly p, ring lmRing, ring tailRing)
+{
+  PrintS(p_String(p, lmRing, tailRing));
+}
+
+/*2
+* writes a polynomial p to stdout followed by \n
+*/
+void p_Write(poly p, ring lmRing, ring tailRing)
+{
+  p_Write0(p, lmRing, tailRing);
+  PrintLn();
+}
+
+/*2
+*the standard debugging output:
+*print the first two monomials of the poly (wrp) or only the lead term (wrp0),
+*possibly followed by the string "+..."
+*/
+void p_wrp0(poly p, ring ri)
+{
+  poly r;
+
+  if (p==NULL) PrintS("NULL");
+  else if (pNext(p)==NULL) p_Write0(p, ri);
+  else
+  {
+    r = pNext(p);
+    pNext(p) = NULL;
+    p_Write0(p, ri);
+    if (r!=NULL)
+    {
+      PrintS("+...");
+      pNext(p) = r;
+    }
+  }
+}
+#if 1
+void p_wrp(poly p, ring lmRing, ring tailRing)
+{
+  poly r;
+
+  if (p==NULL) PrintS("NULL");
+  else if (pNext(p)==NULL) p_Write0(p, lmRing);
+  else
+  {
+    r = pNext(pNext(p));
+    pNext(pNext(p)) = NULL;
+    p_Write0(p, lmRing, tailRing);
+    if (r!=NULL)
+    {
+      PrintS("+...");
+      pNext(pNext(p)) = r;
+    }
+  }
+}
+#else
+// this is for use with buckets
+void p_wrp(poly p, ring lmRing, ring tailRing)
+{
+  poly r;
+
+  if (p==NULL) PrintS("NULL");
+  else if (pNext(p)==NULL) p_Write0(p, lmRing);
+  else
+  {
+    r = pNext(p);
+    pNext(p) = NULL;
+    p_Write0(p, lmRing, tailRing);
+    pNext(p) = r;
+  }
+}
+#endif
Index: kernel/polys1.cc
===================================================================
--- kernel/polys1.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/polys1.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1473 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: polys1.cc,v 1.1.1.1 2003-10-06 12:15:55 Singular Exp $ */
+
+/*
+* ABSTRACT - all basic methods to manipulate polynomials:
+* independent of representation
+*/
+
+/* includes */
+#include <string.h>
+#include "mod2.h"
+#include "structs.h"
+#include "numbers.h"
+#include "ffields.h"
+#include "omalloc.h"
+#include "febase.h"
+#include "weight.h"
+#include "intvec.h"
+#include "longalg.h"
+#include "ring.h"
+#include "ideals.h"
+#include "polys.h"
+//#include "ipid.h"
+#ifdef HAVE_FACTORY
+#include "clapsing.h"
+#endif
+
+/*-------- several access procedures to monomials -------------------- */
+/*
+* the module weights for std
+*/
+static pFDegProc pOldFDeg;
+static pLDegProc pOldLDeg;
+static intvec * pModW;
+static BOOLEAN pOldLexOrder;
+
+static long pModDeg(poly p, ring r = currRing)
+{
+  return pOldFDeg(p, r)+(*pModW)[p_GetComp(p, r)-1];
+}
+
+void pSetModDeg(intvec *w)
+{
+  if (w!=NULL)
+  {
+    pModW = w;
+    pOldFDeg = pFDeg;
+    pOldLDeg = pLDeg;
+    pOldLexOrder = pLexOrder;
+    pSetDegProcs(pModDeg);
+    pLexOrder = TRUE;
+  }
+  else
+  {
+    pModW = NULL;
+    pRestoreDegProcs(pOldFDeg, pOldLDeg);
+    pLexOrder = pOldLexOrder;
+  }
+}
+
+
+/*2
+* subtract p2 from p1, p1 and p2 are destroyed
+* do not put attention on speed: the procedure is only used in the interpreter
+*/
+poly pSub(poly p1, poly p2)
+{
+  return pAdd(p1, pNeg(p2));
+}
+
+/*3
+*  create binomial coef.
+*/
+static number* pnBin(int exp)
+{
+  int e, i, h;
+  number x, y, *bin=NULL;
+
+  x = nInit(exp);
+  if (nIsZero(x))
+  {
+    nDelete(&x);
+    return bin;
+  }
+  h = (exp >> 1) + 1;
+  bin = (number *)omAlloc0(h*sizeof(number));
+  bin[1] = x;
+  if (exp < 4)
+    return bin;
+  i = exp - 1;
+  for (e=2; e<h; e++)
+  {
+//    if(!nIsZero(bin[e-1]))
+//    {
+      x = nInit(i);
+      i--;
+      y = nMult(x,bin[e-1]);
+      nDelete(&x);
+      x = nInit(e);
+      bin[e] = nIntDiv(y,x);
+      nDelete(&x);
+      nDelete(&y);
+//    }
+//    else
+//    {
+//      bin[e] = nInit(binom(exp,e));
+//    }
+  }
+  return bin;
+}
+
+static void pnFreeBin(number *bin, int exp)
+{
+  int e, h = (exp >> 1) + 1;
+
+  if (bin[1] != NULL)
+  {
+    for (e=1; e<h; e++)
+      nDelete(&(bin[e]));
+  }
+  omFreeSize((ADDRESS)bin, h*sizeof(number));
+}
+
+/*3
+* compute for a monomial m
+* the power m^exp, exp > 1
+* destroys p
+*/
+static poly pMonPower(poly p, int exp)
+{
+  int i;
+
+  if(!nIsOne(pGetCoeff(p)))
+  {
+    number x, y;
+    y = pGetCoeff(p);
+    nPower(y,exp,&x);
+    nDelete(&y);
+    pSetCoeff0(p,x);
+  }
+  for (i=pVariables; i!=0; i--)
+  {
+    pMultExp(p,i, exp);
+  }
+  pSetm(p);
+  return p;
+}
+
+/*3
+* compute for monomials p*q
+* destroys p, keeps q
+*/
+static void pMonMult(poly p, poly q)
+{
+  number x, y;
+  int i;
+
+  y = pGetCoeff(p);
+  x = nMult(y,pGetCoeff(q));
+  nDelete(&y);
+  pSetCoeff0(p,x);
+  //for (i=pVariables; i!=0; i--)
+  //{
+  //  pAddExp(p,i, pGetExp(q,i));
+  //}
+  //p->Order += q->Order;
+  pExpVectorAdd(p,q);
+}
+
+/*3
+* compute for monomials p*q
+* keeps p, q
+*/
+static poly pMonMultC(poly p, poly q)
+{
+  number x;
+  int i;
+  poly r = pInit();
+
+  x = nMult(pGetCoeff(p),pGetCoeff(q));
+  pSetCoeff0(r,x);
+  pExpVectorSum(r,p, q);
+  return r;
+}
+
+/*
+*  compute for a poly p = head+tail, tail is monomial
+*          (head + tail)^exp, exp > 1
+*          with binomial coef.
+*/
+static poly pTwoMonPower(poly p, int exp)
+{
+  int eh, e, al;
+  poly *a;
+  poly tail, b, res, h;
+  number x;
+  number *bin = pnBin(exp);
+
+  tail = pNext(p);
+  if (bin == NULL)
+  {
+    pMonPower(p,exp);
+    pMonPower(tail,exp);
+#ifdef PDEBUG
+    pTest(p);
+#endif
+    return p;
+  }
+  eh = exp >> 1;
+  al = (exp + 1) * sizeof(poly);
+  a = (poly *)omAlloc(al);
+  a[1] = p;
+  for (e=1; e<exp; e++)
+  {
+    a[e+1] = pMonMultC(a[e],p);
+  }
+  res = a[exp];
+  b = pHead(tail);
+  for (e=exp-1; e>eh; e--)
+  {
+    h = a[e];
+    x = nMult(bin[exp-e],pGetCoeff(h));
+    pSetCoeff(h,x);
+    pMonMult(h,b);
+    res = pNext(res) = h;
+    pMonMult(b,tail);
+  }
+  for (e=eh; e!=0; e--)
+  {
+    h = a[e];
+    x = nMult(bin[e],pGetCoeff(h));
+    pSetCoeff(h,x);
+    pMonMult(h,b);
+    res = pNext(res) = h;
+    pMonMult(b,tail);
+  }
+  pDeleteLm(&tail);
+  pNext(res) = b;
+  pNext(b) = NULL;
+  res = a[exp];
+  omFreeSize((ADDRESS)a, al);
+  pnFreeBin(bin, exp);
+//  tail=res;
+// while((tail!=NULL)&&(pNext(tail)!=NULL))
+// {
+//   if(nIsZero(pGetCoeff(pNext(tail))))
+//   {
+//     pDeleteLm(&pNext(tail));
+//   }
+//   else
+//     pIter(tail);
+// }
+#ifdef PDEBUG
+  pTest(res);
+#endif
+  return res;
+}
+
+static poly pPow(poly p, int i)
+{
+  poly rc = pCopy(p);
+  i -= 2;
+  do
+  {
+    rc = pMult(rc,pCopy(p));
+    pNormalize(rc);
+    i--;
+  }
+  while (i != 0);
+  return pMult(rc,p);
+}
+
+/*2
+* returns the i-th power of p
+* p will be destroyed
+*/
+poly pPower(poly p, int i)
+{
+  poly rc=NULL;
+
+  if (i==0)
+  {
+    pDelete(&p);
+    return pOne();
+  }
+
+  if(p!=NULL)
+  {
+    if ( (i > 0) && ((unsigned long ) i > (currRing->bitmask)))
+    {
+      Werror("exponent %d is too large, max. is %d",i,currRing->bitmask);
+      return NULL;
+    }
+    switch (i)
+    {
+// cannot happen, see above
+//      case 0:
+//      {
+//        rc=pOne();
+//#ifdef DRING
+//        if ((pDRING) && (pdDFlag(p)==1))
+//        {
+//          pdSetDFlag(rc,1);
+//        }
+//#endif
+//        pDelete(&p);
+//        break;
+//      }
+      case 1:
+        rc=p;
+        break;
+      case 2:
+        rc=pMult(pCopy(p),p);
+        break;
+      default:
+        if (i < 0)
+        {
+          pDelete(&p);
+          return NULL;
+        }
+        else
+        {
+          rc = pNext(p);
+          if (rc == NULL)
+            return pMonPower(p,i);
+          /* else: binom ?*/
+          int char_p=rChar(currRing);
+          if (pNext(rc) != NULL)
+            return pPow(p,i);
+          if ((char_p==0) || (i<=char_p))
+            return pTwoMonPower(p,i);
+          poly p_p=pTwoMonPower(pCopy(p),char_p);
+          return pMult(pPower(p,i-char_p),p_p);
+        }
+      /*end default:*/
+    }
+  }
+  return rc;
+}
+
+/*2
+* returns the partial differentiate of a by the k-th variable
+* does not destroy the input
+*/
+poly pDiff(poly a, int k)
+{
+  poly res, f, last;
+  number t;
+
+  last = res = NULL;
+  while (a!=NULL)
+  {
+    if (pGetExp(a,k)!=0)
+    {
+      f = pLmInit(a);
+      t = nInit(pGetExp(a,k));
+      pSetCoeff0(f,nMult(t,pGetCoeff(a)));
+      nDelete(&t);
+      if (nIsZero(pGetCoeff(f)))
+        pDeleteLm(&f);
+      else
+      {
+        pDecrExp(f,k);
+        pSetm(f);
+        if (res==NULL)
+        {
+          res=last=f;
+        }
+        else
+        {
+          pNext(last)=f;
+          last=f;
+        }
+      }
+    }
+    pIter(a);
+  }
+  return res;
+}
+
+static poly pDiffOpM(poly a, poly b,BOOLEAN multiply)
+{
+  int i,j,s;
+  number n,h,hh;
+  poly p=pOne();
+  n=nMult(pGetCoeff(a),pGetCoeff(b));
+  for(i=pVariables;i>0;i--)
+  {
+    s=pGetExp(b,i);
+    if (s<pGetExp(a,i))
+    {
+      nDelete(&n);
+      pDeleteLm(&p);
+      return NULL;
+    }
+    if (multiply)
+    {
+      for(j=pGetExp(a,i); j>0;j--)
+      {
+        h = nInit(s);
+        hh=nMult(n,h);
+        nDelete(&h);
+        nDelete(&n);
+        n=hh;
+        s--;
+      }
+      pSetExp(p,i,s);
+    }
+    else
+    {
+      pSetExp(p,i,s-pGetExp(a,i));
+    }
+  }
+  pSetm(p);
+  /*if (multiply)*/ pSetCoeff(p,n);
+  return p;
+}
+
+poly pDiffOp(poly a, poly b,BOOLEAN multiply)
+{
+  poly result=NULL;
+  poly h;
+  for(;a!=NULL;pIter(a))
+  {
+    for(h=b;h!=NULL;pIter(h))
+    {
+      result=pAdd(result,pDiffOpM(a,h,multiply));
+    }
+  }
+  return result;
+}
+
+
+void pSplit(poly p, poly *h)
+{
+  *h=pNext(p);
+  pNext(p)=NULL;
+}
+
+
+
+int pMaxCompProc(poly p)
+{
+  return pMaxComp(p);
+}
+
+/*2
+* handle memory request for sets of polynomials (ideals)
+* l is the length of *p, increment is the difference (may be negative)
+*/
+void pEnlargeSet(polyset *p, int l, int increment)
+{
+  int i;
+  polyset h;
+
+  h=(polyset)omReallocSize((poly*)*p,l*sizeof(poly),(l+increment)*sizeof(poly));
+  if (increment>0)
+  {
+    //for (i=l; i<l+increment; i++)
+    //  h[i]=NULL;
+    memset(&(h[l]),0,increment*sizeof(poly));
+  }
+  *p=h;
+}
+
+void pContent(poly ph)
+{
+  number h,d;
+  poly p;
+
+  if(TEST_OPT_CONTENTSB) return;
+  if(pNext(ph)==NULL)
+  {
+    pSetCoeff(ph,nInit(1));
+  }
+  else
+  {
+    nNormalize(pGetCoeff(ph));
+    if(!nGreaterZero(pGetCoeff(ph))) ph = pNeg(ph);
+    h=nCopy(pGetCoeff(ph));
+    p = pNext(ph);
+    while (p!=NULL)
+    {
+      nNormalize(pGetCoeff(p));
+      d=nGcd(h,pGetCoeff(p),currRing);
+      nDelete(&h);
+      h = d;
+      if(nIsOne(h))
+      {
+        break;
+      }
+      pIter(p);
+    }
+    p = ph;
+    //number tmp;
+    if(!nIsOne(h))
+    {
+      while (p!=NULL)
+      {
+        //d = nDiv(pGetCoeff(p),h);
+        //tmp = nIntDiv(pGetCoeff(p),h);
+        //if (!nEqual(d,tmp))
+        //{
+        //  StringSetS("** div0:");nWrite(pGetCoeff(p));StringAppendS("/");
+        //  nWrite(h);StringAppendS("=");nWrite(d);StringAppendS(" int:");
+        //  nWrite(tmp);Print(StringAppendS("\n"));
+        //}
+        //nDelete(&tmp);
+        d = nIntDiv(pGetCoeff(p),h);
+        pSetCoeff(p,d);
+        pIter(p);
+      }
+    }
+    nDelete(&h);
+#ifdef HAVE_FACTORY
+    if ( (nGetChar() == 1) || (nGetChar() < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
+    {
+      singclap_divide_content(ph);
+      if(!nGreaterZero(pGetCoeff(ph))) ph = pNeg(ph);
+    }
+#endif
+  }
+}
+
+//void pContent(poly ph)
+//{
+//  number h,d;
+//  poly p;
+//
+//  p = ph;
+//  if(pNext(p)==NULL)
+//  {
+//    pSetCoeff(p,nInit(1));
+//  }
+//  else
+//  {
+//#ifdef PDEBUG
+//    if (!pTest(p)) return;
+//#endif
+//    nNormalize(pGetCoeff(p));
+//    if(!nGreaterZero(pGetCoeff(ph)))
+//    {
+//      ph = pNeg(ph);
+//      nNormalize(pGetCoeff(p));
+//    }
+//    h=pGetCoeff(p);
+//    pIter(p);
+//    while (p!=NULL)
+//    {
+//      nNormalize(pGetCoeff(p));
+//      if (nGreater(h,pGetCoeff(p))) h=pGetCoeff(p);
+//      pIter(p);
+//    }
+//    h=nCopy(h);
+//    p=ph;
+//    while (p!=NULL)
+//    {
+//      d=nGcd(h,pGetCoeff(p));
+//      nDelete(&h);
+//      h = d;
+//      if(nIsOne(h))
+//      {
+//        break;
+//      }
+//      pIter(p);
+//    }
+//    p = ph;
+//    //number tmp;
+//    if(!nIsOne(h))
+//    {
+//      while (p!=NULL)
+//      {
+//        d = nIntDiv(pGetCoeff(p),h);
+//        pSetCoeff(p,d);
+//        pIter(p);
+//      }
+//    }
+//    nDelete(&h);
+//#ifdef HAVE_FACTORY
+//    if ( (nGetChar() == 1) || (nGetChar() < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
+//    {
+//      pTest(ph);
+//      singclap_divide_content(ph);
+//      pTest(ph);
+//    }
+//#endif
+//  }
+//}
+void p_Content(poly ph, ring r)
+{
+  number h,d;
+  poly p;
+
+  if(pNext(ph)==NULL)
+  {
+    pSetCoeff(ph,n_Init(1,r));
+  }
+  else
+  {
+    n_Normalize(pGetCoeff(ph),r);
+    if(!n_GreaterZero(pGetCoeff(ph),r)) ph = p_Neg(ph,r);
+    h=n_Copy(pGetCoeff(ph),r);
+    p = pNext(ph);
+    while (p!=NULL)
+    {
+      n_Normalize(pGetCoeff(p),r);
+      d=n_Gcd(h,pGetCoeff(p),r);
+      n_Delete(&h,r);
+      h = d;
+      if(n_IsOne(h,r))
+      {
+        break;
+      }
+      pIter(p);
+    }
+    p = ph;
+    //number tmp;
+    if(!n_IsOne(h,r))
+    {
+      while (p!=NULL)
+      {
+        //d = nDiv(pGetCoeff(p),h);
+        //tmp = nIntDiv(pGetCoeff(p),h);
+        //if (!nEqual(d,tmp))
+        //{
+        //  StringSetS("** div0:");nWrite(pGetCoeff(p));StringAppendS("/");
+        //  nWrite(h);StringAppendS("=");nWrite(d);StringAppendS(" int:");
+        //  nWrite(tmp);Print(StringAppendS("\n"));
+        //}
+        //nDelete(&tmp);
+        d = n_IntDiv(pGetCoeff(p),h,r);
+        p_SetCoeff(p,d,r);
+        pIter(p);
+      }
+    }
+    n_Delete(&h,r);
+#ifdef HAVE_FACTORY
+    //if ( (nGetChar() == 1) || (nGetChar() < 0) ) /* Q[a],Q(a),Zp[a],Z/p(a) */
+    //{
+    //  singclap_divide_content(ph);
+    //  if(!nGreaterZero(pGetCoeff(ph))) ph = pNeg(ph);
+    //}
+#endif
+  }
+}
+
+void pCleardenom(poly ph)
+{
+  number d, h;
+  poly p;
+
+  p = ph;
+  if(pNext(p)==NULL)
+  {
+    if (TEST_OPT_CONTENTSB)
+    {
+      number n=nGetDenom(pGetCoeff(p));
+      if (!nIsOne(n))
+      {
+        number nn=nMult(pGetCoeff(p),n);
+	nNormalize(nn);
+        pSetCoeff(p,nn);
+      }
+      nDelete(&n);
+    }
+    else
+      pSetCoeff(p,nInit(1));
+  }
+  else
+  {
+    h = nInit(1);
+    while (p!=NULL)
+    {
+      nNormalize(pGetCoeff(p));
+      d=nLcm(h,pGetCoeff(p),currRing);
+      nDelete(&h);
+      h=d;
+      pIter(p);
+    }
+    /* contains the 1/lcm of all denominators */
+    if(!nIsOne(h))
+    {
+      p = ph;
+      while (p!=NULL)
+      {
+        /* should be:
+        * number hh;
+        * nGetDenom(p->coef,&hh);
+        * nMult(&h,&hh,&d);
+        * nNormalize(d);
+        * nDelete(&hh);
+        * nMult(d,p->coef,&hh);
+        * nDelete(&d);
+        * nDelete(&(p->coef));
+        * p->coef =hh;
+        */
+        d=nMult(h,pGetCoeff(p));
+        nNormalize(d);
+        pSetCoeff(p,d);
+        pIter(p);
+      }
+      nDelete(&h);
+      if (nGetChar()==1)
+      {
+        loop
+        {
+          h = nInit(1);
+          p=ph;
+          while (p!=NULL)
+          {
+            d=nLcm(h,pGetCoeff(p),currRing);
+            nDelete(&h);
+            h=d;
+            pIter(p);
+          }
+          /* contains the 1/lcm of all denominators */
+          if(!nIsOne(h))
+          {
+            p = ph;
+            while (p!=NULL)
+            {
+              /* should be:
+              * number hh;
+              * nGetDenom(p->coef,&hh);
+              * nMult(&h,&hh,&d);
+              * nNormalize(d);
+              * nDelete(&hh);
+              * nMult(d,p->coef,&hh);
+              * nDelete(&d);
+              * nDelete(&(p->coef));
+              * p->coef =hh;
+              */
+              d=nMult(h,pGetCoeff(p));
+              nNormalize(d);
+              pSetCoeff(p,d);
+              pIter(p);
+            }
+            nDelete(&h);
+          }
+          else
+          {
+            nDelete(&h);
+            break;
+          }
+        }
+      }
+    }
+    if (h!=NULL) nDelete(&h);
+    pContent(ph);
+  }
+}
+
+/*2
+*tests if p is homogeneous with respect to the actual weigths
+*/
+BOOLEAN pIsHomogeneous (poly p)
+{
+  poly qp=p;
+  int o;
+
+  if ((p == NULL) || (pNext(p) == NULL)) return TRUE;
+  pFDegProc d=(pLexOrder ? pTotaldegree : pFDeg );
+  o = d(p);
+  do
+  {
+    if (d(qp) != o) return FALSE;
+    pIter(qp);
+  }
+  while (qp != NULL);
+  return TRUE;
+}
+
+// orders monoms of poly using merge sort (ususally faster than
+// insertion sort). ASSUMES that pSetm was performed on monoms
+poly pOrdPolyMerge(poly p)
+{
+  poly qq,pp,result=NULL;
+
+  if (p == NULL) return NULL;
+
+  loop
+  {
+    qq = p;
+    loop
+    {
+      if (pNext(p) == NULL)
+      {
+        result=pAdd(result, qq);
+        pTest(result);
+        return result;
+      }
+      if (pLmCmp(p,pNext(p)) != 1)
+      {
+        pp = p;
+        pIter(p);
+        pNext(pp) = NULL;
+        result = pAdd(result, qq);
+        break;
+      }
+      pIter(p);
+    }
+  }
+}
+
+// orders monoms of poly using insertion sort, performs pSetm on each monom
+poly pOrdPolyInsertSetm(poly p)
+{
+  poly qq,result = NULL;
+
+#if 0
+  while (p != NULL)
+  {
+    qq = p;
+    pIter(p);
+    qq->next = NULL;
+    pSetm(qq);
+    result = pAdd(result,qq);
+    pTest(result);
+  }
+#else
+  while (p != NULL)
+  {
+    qq = p;
+    pIter(p);
+    qq->next = result;
+    result = qq;
+    pSetm(qq);
+  }
+  p = result;
+  result = NULL;
+  while (p != NULL)
+  {
+    qq = p;
+    pIter(p);
+    qq->next = NULL;
+    result = pAdd(result, qq);
+  }
+  pTest(result);
+#endif
+  return result;
+}
+
+/*2
+*returns a re-ordered copy of a polynomial, with permutation of the variables
+*/
+poly pPermPoly (poly p, int * perm, ring oldRing, nMapFunc nMap,
+   int *par_perm, int OldPar)
+{
+  int OldpVariables = oldRing->N;
+  poly result = NULL;
+  poly result_last = NULL;
+  poly aq=NULL; /* the map coefficient */
+  poly qq; /* the mapped monomial */
+
+  while (p != NULL)
+  {
+    if ((OldPar==0)||(rField_is_GF(oldRing)))
+    {
+      qq = pInit();
+      number n=nMap(pGetCoeff(p));
+      if ((currRing->minpoly!=NULL)
+      && ((rField_is_Zp_a()) || (rField_is_Q_a())))
+      {
+        nNormalize(n);
+      }
+      pGetCoeff(qq)=n;
+    // coef may be zero:  pTest(qq);
+    }
+    else
+    {
+      qq=pOne();
+      aq=naPermNumber(pGetCoeff(p),par_perm,OldPar, oldRing);
+      if ((currRing->minpoly!=NULL)
+      && ((rField_is_Zp_a()) || (rField_is_Q_a())))
+      {
+        poly tmp=aq;
+        while (tmp!=NULL)
+        {
+          number n=pGetCoeff(tmp);
+          nNormalize(n);
+          pGetCoeff(tmp)=n;
+          pIter(tmp);
+        }
+      }
+      pTest(aq);
+    }
+    pSetComp(qq, p_GetComp(p,oldRing));
+    if (nIsZero(pGetCoeff(qq)))
+    {
+      pDeleteLm(&qq);
+    }
+    else
+    {
+      int i;
+      int mapped_to_par=0;
+      for(i=1; i<=OldpVariables; i++)
+      {
+        int e=p_GetExp(p,i,oldRing);
+        if (e!=0)
+        {
+          if (perm==NULL)
+          {
+            pSetExp(qq,i, e);
+          }
+          else if (perm[i]>0)
+            pAddExp(qq,perm[i], e/*p_GetExp( p,i,oldRing)*/);
+          else if (perm[i]<0)
+          {
+            if (rField_is_GF())
+            {
+              number c=pGetCoeff(qq);
+              number ee=nfPar(1);
+              number eee;nfPower(ee,e,&eee); //nfDelete(ee,currRing);
+              ee=nfMult(c,eee);
+              //nfDelete(c,currRing);nfDelete(eee,currRing);
+              pSetCoeff0(qq,ee);
+            }
+            else
+            {
+              lnumber c=(lnumber)pGetCoeff(qq);
+              napAddExp(c->z,-perm[i],e/*p_GetExp( p,i,oldRing)*/);
+              mapped_to_par=1;
+            }
+          }
+          else
+          {
+            /* this variable maps to 0 !*/
+            pDeleteLm(&qq);
+            break;
+          }
+        }
+      }
+      if (mapped_to_par
+      && (currRing->minpoly!=NULL))
+      {
+        number n=pGetCoeff(qq);
+        nNormalize(n);
+        pGetCoeff(qq)=n;
+      }
+    }
+    pIter(p);
+#if 1
+    if (qq!=NULL)
+    {
+      pSetm(qq);
+      pTest(aq);
+      pTest(qq);
+      if (aq!=NULL) qq=pMult(aq,qq);
+      aq = qq;
+      while (pNext(aq) != NULL) pIter(aq);
+      if (result_last==NULL)
+      {
+        result=qq;
+      }
+      else
+      {
+        pNext(result_last)=qq;
+      }
+      result_last=aq;
+      aq = NULL;
+    }
+    else if (aq!=NULL)
+    {
+      pDelete(&aq);
+    }
+  }
+  result=pSortAdd(result);
+#else
+  //  if (qq!=NULL)
+  //  {
+  //    pSetm(qq);
+  //    pTest(qq);
+  //    pTest(aq);
+  //    if (aq!=NULL) qq=pMult(aq,qq);
+  //    aq = qq;
+  //    while (pNext(aq) != NULL) pIter(aq);
+  //    pNext(aq) = result;
+  //    aq = NULL;
+  //    result = qq;
+  //  }
+  //  else if (aq!=NULL)
+  //  {
+  //    pDelete(&aq);
+  //  }
+  //}
+  //p = result;
+  //result = NULL;
+  //while (p != NULL)
+  //{
+  //  qq = p;
+  //  pIter(p);
+  //  qq->next = NULL;
+  //  result = pAdd(result, qq);
+  //}
+#endif
+  pTest(result);
+  return result;
+}
+
+#if 0
+/*2
+*returns a re-ordered copy of a polynomial, with permutation of the variables
+*/
+poly p_PermPoly (poly p, int * perm, ring oldRing,
+   int *par_perm, int OldPar, ring newRing)
+{
+  int OldpVariables = oldRing->N;
+  poly result = NULL;
+  poly result_last = NULL;
+  poly aq=NULL; /* the map coefficient */
+  poly qq; /* the mapped monomial */
+
+  while (p != NULL)
+  {
+    if (OldPar==0)
+    {
+      qq = pInit();
+      number n=newRing->cf->nMap(pGetCoeff(p));
+      if ((newRing->minpoly!=NULL)
+      && ((rField_is_Zp_a(newRing)) || (rField_is_Q_a(newRing))))
+      {
+        newRing->cf->nNormalize(n);
+      }
+      pGetCoeff(qq)=n;
+    // coef may be zero:  pTest(qq);
+    }
+    else
+    {
+      qq=p_ISet(1, newRing);
+      aq=naPermNumber(pGetCoeff(p),par_perm,OldPar, oldRing);
+      if ((newRing->minpoly!=NULL)
+      && ((rField_is_Zp_a(newRing)) || (rField_is_Q_a(newRing))))
+      {
+        poly tmp=aq;
+        while (tmp!=NULL)
+        {
+          number n=pGetCoeff(tmp);
+          newRing->cf->nNormalize(n);
+          pGetCoeff(tmp)=n;
+          pIter(tmp);
+        }
+      }
+      //pTest(aq);
+    }
+    p_SetComp(qq, p_GetComp(p,oldRing), newRing);
+    if (newRing->cf->nIsZero(pGetCoeff(qq)))
+    {
+      p_DeleteLm(&qq, newRing);
+    }
+    else
+    {
+      int i;
+      int mapped_to_par=0;
+      for(i=1; i<=OldpVariables; i++)
+      {
+        int e=p_GetExp(p,i,oldRing);
+        if (e!=0)
+        {
+          if (perm==NULL)
+          {
+            p_SetExp(qq,i, e, newRing);
+          }
+          else if (perm[i]>0)
+            p_AddExp(qq,perm[i], e/*p_GetExp( p,i,oldRing)*/, newRing);
+          else if (perm[i]<0)
+          {
+            lnumber c=(lnumber)pGetCoeff(qq);
+            napAddExp(c->z,-perm[i],e/*p_GetExp( p,i,oldRing)*/);
+            mapped_to_par=1;
+          }
+          else
+          {
+            /* this variable maps to 0 !*/
+            p_DeleteLm(&qq, newRing);
+            break;
+          }
+        }
+      }
+      if (mapped_to_par
+      && (newRing->minpoly!=NULL))
+      {
+        number n=pGetCoeff(qq);
+        newRing->cf->nNormalize(n);
+        pGetCoeff(qq)=n;
+      }
+    }
+    pIter(p);
+    if (qq!=NULL)
+    {
+      p_Setm(qq, newRing);
+      //pTest(aq);
+      //pTest(qq);
+      if (aq!=NULL) qq=pMult(aq,qq);
+      aq = qq;
+      while (pNext(aq) != NULL) pIter(aq);
+      if (result_last==NULL)
+      {
+        result=qq;
+      }
+      else
+      {
+        pNext(result_last)=qq;
+      }
+      result_last=aq;
+      aq = NULL;
+    }
+    else if (aq!=NULL)
+    {
+      p_Delete(&aq, newRing);
+    }
+  }
+  result=pOrdPolyMerge(result);
+  //pTest(result);
+  return result;
+}
+#endif
+
+poly ppJet(poly p, int m)
+{
+  poly r=NULL;
+  poly t=NULL;
+
+  while (p!=NULL)
+  {
+    if (pTotaldegree(p)<=m)
+    {
+      if (r==NULL)
+        r=pHead(p);
+      else
+      if (t==NULL)
+      {
+        pNext(r)=pHead(p);
+        t=pNext(r);
+      }
+      else
+      {
+        pNext(t)=pHead(p);
+        pIter(t);
+      }
+    }
+    pIter(p);
+  }
+  return r;
+}
+
+poly pJet(poly p, int m)
+{
+  poly t=NULL;
+
+  while((p!=NULL) && (pTotaldegree(p)>m)) pLmDelete(&p);
+  if (p==NULL) return NULL;
+  poly r=p;
+  while (pNext(p)!=NULL)
+  {
+    if (pTotaldegree(pNext(p))>m)
+    {
+      pLmDelete(&pNext(p));
+    }
+    else
+      pIter(p);
+  }
+  return r;
+}
+
+poly ppJetW(poly p, int m, short *w)
+{
+  poly r=NULL;
+  poly t=NULL;
+  while (p!=NULL)
+  {
+    if (totaldegreeWecart_IV(p,currRing,w)<=m)
+    {
+      if (r==NULL)
+        r=pHead(p);
+      else
+      if (t==NULL)
+      {
+        pNext(r)=pHead(p);
+        t=pNext(r);
+      }
+      else
+      {
+        pNext(t)=pHead(p);
+        pIter(t);
+      }
+    }
+    pIter(p);
+  }
+  return r;
+}
+
+poly pJetW(poly p, int m, short *w)
+{
+  poly t=NULL;
+  while((p!=NULL) && (totaldegreeWecart_IV(p,currRing,w)>m)) pLmDelete(&p);
+  if (p==NULL) return NULL;
+  poly r=p;
+  while (pNext(p)!=NULL)
+  {
+    if (totaldegreeWecart_IV(pNext(p),currRing,w)>m)
+    {
+      pLmDelete(&pNext(p));
+    }
+    else
+      pIter(p);
+  }
+  return r;
+}
+
+int pMinDeg(poly p,intvec *w)
+{
+  if(p==NULL)
+    return -1;
+  int d=-1;
+  while(p!=NULL)
+  {
+    int d0=0;
+    for(int j=0;j<pVariables;j++)
+      if(w==NULL||j>=w->length())
+        d0+=pGetExp(p,j+1);
+      else
+        d0+=(*w)[j]*pGetExp(p,j+1);
+    if(d0<d||d==-1)
+      d=d0;
+    pIter(p);
+  }
+  return d;
+}
+
+poly pSeries(int n,poly p,poly u, intvec *w)
+{
+  short *ww=iv2array(w);
+  if(p!=NULL)
+  {
+    if(u==NULL)
+      p=pJetW(p,n,ww);
+    else
+      p=pJetW(pMult(p,pInvers(n-pMinDeg(p,w),u,w)),n,ww);
+  }
+  omFreeSize((ADDRESS)ww,(pVariables+1)*sizeof(short));
+  return p;
+}
+
+poly pInvers(int n,poly u,intvec *w)
+{
+  short *ww=iv2array(w);
+  if(n<0)
+    return NULL;
+  number u0=nInvers(pGetCoeff(u));
+  poly v=pNSet(u0);
+  if(n==0)
+    return v;
+  poly u1=pJetW(pSub(pOne(),pMult_nn(u,u0)),n,ww);
+  if(u1==NULL)
+    return v;
+  poly v1=pMult_nn(pCopy(u1),u0);
+  v=pAdd(v,pCopy(v1));
+  for(int i=n/pMinDeg(u1,w);i>1;i--)
+  {
+    v1=pJetW(pMult(v1,pCopy(u1)),n,ww);
+    v=pAdd(v,pCopy(v1));
+  }
+  pDelete(&u1);
+  pDelete(&v1);
+  omFreeSize((ADDRESS)ww,(pVariables+1)*sizeof(short));
+  return v;
+}
+
+long pDegW(poly p, short *w)
+{
+  long r=-LONG_MAX;
+
+  while (p!=NULL)
+  {
+    r=si_max(r, totaldegreeWecart_IV(p,currRing,w));
+    pIter(p);
+  }
+  return r;
+}
+
+/*-----------type conversions ----------------------------*/
+/*2
+* input: a set of polys (len elements: p[0]..p[len-1])
+* output: a vector
+* p will not be changed
+*/
+poly  pPolys2Vec(polyset p, int len)
+{
+  poly v=NULL;
+  poly h;
+  int i;
+
+  for (i=len-1; i>=0; i--)
+  {
+    if (p[i])
+    {
+      h=pCopy(p[i]);
+      pSetCompP(h,i+1);
+      v=pAdd(v,h);
+    }
+  }
+ return v;
+}
+
+/*2
+* convert a vector to a set of polys,
+* allocates the polyset, (entries 0..(*len)-1)
+* the vector will not be changed
+*/
+void  pVec2Polys(poly v, polyset *p, int *len)
+{
+  poly h;
+  int k;
+
+  *len=pMaxComp(v);
+  if (*len==0) *len=1;
+  *p=(polyset)omAlloc0((*len)*sizeof(poly));
+  while (v!=NULL)
+  {
+    h=pHead(v);
+    k=pGetComp(h);
+    pSetComp(h,0);
+    (*p)[k-1]=pAdd((*p)[k-1],h);
+    pIter(v);
+  }
+}
+
+int pVar(poly m)
+{
+  if (m==NULL) return 0;
+  if (pNext(m)!=NULL) return 0;
+  int i,e=0;
+  for (i=pVariables; i>0; i--)
+  {
+    if (pGetExp(m,i)==1)
+    {
+      if (e==0) e=i;
+      else return 0;
+    }
+  }
+  return e;
+}
+
+/*----------utilities for syzygies--------------*/
+//BOOLEAN   pVectorHasUnitM(poly p, int * k)
+//{
+//  while (p!=NULL)
+//  {
+//    if (pLmIsConstantComp(p))
+//    {
+//      *k = pGetComp(p);
+//      return TRUE;
+//    }
+//    else pIter(p);
+//  }
+//  return FALSE;
+//}
+
+BOOLEAN   pVectorHasUnitB(poly p, int * k)
+{
+  poly q=p,qq;
+  int i;
+
+  while (q!=NULL)
+  {
+    if (pLmIsConstantComp(q))
+    {
+      i = pGetComp(q);
+      qq = p;
+      while ((qq != q) && (pGetComp(qq) != i)) pIter(qq);
+      if (qq == q)
+      {
+        *k = i;
+        return TRUE;
+      }
+      else
+        pIter(q);
+    }
+    else pIter(q);
+  }
+  return FALSE;
+}
+
+void   pVectorHasUnit(poly p, int * k, int * len)
+{
+  poly q=p,qq;
+  int i,j=0;
+
+  *len = 0;
+  while (q!=NULL)
+  {
+    if (pLmIsConstantComp(q))
+    {
+      i = pGetComp(q);
+      qq = p;
+      while ((qq != q) && (pGetComp(qq) != i)) pIter(qq);
+      if (qq == q)
+      {
+       j = 0;
+       while (qq!=NULL)
+       {
+         if (pGetComp(qq)==i) j++;
+        pIter(qq);
+       }
+       if ((*len == 0) || (j<*len))
+       {
+         *len = j;
+         *k = i;
+       }
+      }
+    }
+    pIter(q);
+  }
+}
+
+/*2
+* returns TRUE if p1 = p2
+*/
+BOOLEAN pEqualPolys(poly p1,poly p2)
+{
+  while ((p1 != NULL) && (p2 != NULL))
+  {
+    if (! pLmEqual(p1, p2))
+      return FALSE;
+    if (! nEqual(pGetCoeff(p1), pGetCoeff(p2)))
+      return FALSE;
+    pIter(p1);
+    pIter(p2);
+  }
+  return (p1==p2);
+}
+
+/*2
+*returns TRUE if p1 is a skalar multiple of p2
+*assume p1 != NULL and p2 != NULL
+*/
+BOOLEAN pComparePolys(poly p1,poly p2)
+{
+  number n,nn;
+  int i;
+  pAssume(p1 != NULL && p2 != NULL);
+
+  if (!pLmEqual(p1,p2)) //compare leading mons
+      return FALSE;
+  if ((pNext(p1)==NULL) && (pNext(p2)!=NULL))
+     return FALSE;
+  if ((pNext(p2)==NULL) && (pNext(p1)!=NULL))
+     return FALSE;
+  if (pLength(p1) != pLength(p2))
+    return FALSE;
+  n=nDiv(pGetCoeff(p1),pGetCoeff(p2));
+  while ((p1 != NULL) /*&& (p2 != NULL)*/)
+  {
+    if ( ! pLmEqual(p1, p2))
+    {
+        nDelete(&n);
+        return FALSE;
+    }
+    if (!nEqual(pGetCoeff(p1),nn=nMult(pGetCoeff(p2),n)))
+    {
+      nDelete(&n);
+      nDelete(&nn);
+      return FALSE;
+    }
+    nDelete(&nn);
+    pIter(p1);
+    pIter(p2);
+  }
+  nDelete(&n);
+  return TRUE;
+}
Index: kernel/pp_Mult_Coeff_mm_DivSelectMult__T.cc
===================================================================
--- kernel/pp_Mult_Coeff_mm_DivSelectMult__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/pp_Mult_Coeff_mm_DivSelectMult__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,79 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pp_Mult_Coeff_mm_DivSelectMult__Template.cc
+ *  Purpose: template for pp_Mult_Coeff_mm__DivSelectMult
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: pp_Mult_Coeff_mm_DivSelectMult__T.cc,v 1.1.1.1 2003-10-06 12:16:01 Singular Exp $
+ *******************************************************************/
+
+/***************************************************************
+ *
+ *   Returns:  p*Coeff(m)*a/b for such monomials pm of p, for which
+ *             m is divisble by pm, shorter == #of monomials left out
+ *   Assumes:  m, a, b are monomials, ordering is (c, dp),
+ *            (p*a) is divisble by b for all monimials in question
+ *   Const:    p, m, a, b
+ *
+ ***************************************************************/
+LINKAGE poly pp_Mult_Coeff_mm_DivSelectMult
+  (poly p,const poly m, const poly a, const poly b, int &shorter,const ring r)
+{
+  assume(rOrd_is_Comp_dp(r) && r->ExpL_Size > 2);
+  p_Test(p, r);
+  if (p == NULL) return NULL;
+  number n = pGetCoeff(m);
+  number nc;
+  pAssume(!n_IsZero(n,r));
+
+  spolyrec rp;
+  omBin bin = r->PolyBin;
+  const unsigned long bitmask = r->divmask;
+  const unsigned long* m_e = &(m->exp[2]);
+  DECLARE_LENGTH(const unsigned long length = r->ExpL_Size);
+  DECLARE_LENGTH_2(const unsigned long length_2 = length - 2);
+
+  poly ab;
+  p_AllocBin(ab, bin, r);
+  unsigned long* ab_e = &(ab->exp[0]);
+
+  p_MemDiff(ab_e, ((unsigned long*) &(a->exp[0])), ((unsigned long*) &(b->exp[0])),
+            length);
+
+  int Shorter = 0;
+  poly q = &rp;
+
+  do
+  {
+    p_MemCmp_Bitmask_2(m_e, &(p->exp[2]), bitmask, length_2,
+                       goto Divisible, goto NotDivisible);
+
+    NotDivisible:
+    pAssume(!p_LmDivisibleByNoComp(m, p, r));
+    Shorter++;
+    goto Iter;
+
+    Divisible:
+    pAssume(p_LmDivisibleByNoComp(m, p, r));
+    p_AllocBin(pNext(q), bin, r);
+    q = pNext(q);
+    nc = pGetCoeff(p);
+    pSetCoeff0(q, n_Mult(n, nc, r));
+    p_MemSum(q->exp, p->exp, ab_e, length);
+
+    Iter:
+    pIter(p);
+  }
+  while (p != NULL);
+
+  pNext(q) = NULL;
+  p_FreeBinAddr(ab, r);
+
+  shorter = Shorter;
+  p_Test(rp.next, r);
+  return rp.next;
+}
+
+
Index: kernel/pp_Mult_Coeff_mm_DivSelect__T.cc
===================================================================
--- kernel/pp_Mult_Coeff_mm_DivSelect__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/pp_Mult_Coeff_mm_DivSelect__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,56 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pp_Mult_Coeff_mm_DivSelect__Template.cc
+ *  Purpose: template for pp_Mult_Coeff_mm__DivSelect
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: pp_Mult_Coeff_mm_DivSelect__T.cc,v 1.1.1.1 2003-10-06 12:16:02 Singular Exp $
+ *******************************************************************/
+
+/***************************************************************
+ *
+ *   Returns:  p*Coeff(m) for such monomials pm of p, for which
+ *             m is divisble by pm
+ *   Const:    p, m
+ *
+ ***************************************************************/
+LINKAGE poly pp_Mult_Coeff_mm_DivSelect(poly p, const poly m, int &shorter,
+                                        const ring r)
+{
+  number n = pGetCoeff(m);
+  pAssume(!n_IsZero(n,r));
+  p_Test(p, r);
+  if (p == NULL) return NULL;
+  spolyrec rp;
+  DECLARE_LENGTH(const unsigned long length = r->ExpL_Size);
+  int Shorter = 0;
+  poly q = &rp;
+  omBin bin = r->PolyBin;
+
+  do
+  {
+    if (p_LmDivisibleByNoComp(m, p, r))
+    {
+      p_AllocBin(pNext(q), bin, r);
+      q = pNext(q);
+      number nc = pGetCoeff(p);
+      pSetCoeff0(q, n_Mult(n, nc, r));
+      p_MemCopy(q->exp, p->exp, length);
+    }
+    else
+    {
+      Shorter++;
+    }
+    pIter(p);
+  }
+  while (p != NULL);
+  pNext(q) = NULL;
+
+  shorter = Shorter;
+  p_Test(rp.next, r);
+  return rp.next;
+}
+
+
Index: kernel/pp_Mult_mm_Noether__T.cc
===================================================================
--- kernel/pp_Mult_mm_Noether__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/pp_Mult_mm_Noether__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,75 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pp_Mult_mm__Template.cc
+ *  Purpose: template for p_Mult_n
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: pp_Mult_mm_Noether__T.cc,v 1.1.1.1 2003-10-06 12:16:02 Singular Exp $
+ *******************************************************************/
+
+/***************************************************************
+ *
+ *   Returns:  p*m, ll
+ *   ll == pLength(p*m) , if on input ll < 0
+ *   pLength(p) - pLength(p*m), if on input ll >= 0
+ *   Const:    p, m
+ *
+ ***************************************************************/
+LINKAGE poly pp_Mult_mm_Noether(poly p, const poly m, const poly spNoether, int &ll, const ring ri, poly &last)
+{
+  p_Test(p, ri);
+  p_LmTest(m, ri);
+  assume(spNoether != NULL);
+  if (p == NULL)
+  {
+    ll = 0;
+    last = NULL;
+    return NULL;
+  }
+  spolyrec rp;
+  poly q = &rp, r;
+  const unsigned long *spNoether_exp = spNoether->exp;
+  number ln = pGetCoeff(m);
+  omBin bin = ri->PolyBin;
+  DECLARE_LENGTH(const unsigned long length = ri->ExpL_Size);
+  DECLARE_ORDSGN(const long* ordsgn = ri->ordsgn);
+  const unsigned long* m_e = m->exp;
+  pAssume(!n_IsZero(ln,ri));
+  pAssume1(p_GetComp(m, ri) == 0 || p_MaxComp(p, ri) == 0);
+  int l = 0;
+
+  do
+  {
+    p_AllocBin(r, bin, ri);
+    p_MemSum(r->exp, p->exp, m_e, length);
+    p_MemAddAdjust(r, ri);
+
+    p_MemCmp(r->exp, spNoether_exp, length, ordsgn, goto Continue, goto Continue, goto Break);
+
+    Break:
+    p_FreeBinAddr(r, ri);
+    break;
+
+    Continue:
+    l++;
+    q = pNext(q) = r;
+    pSetCoeff0(q, n_Mult(ln, pGetCoeff(p), ri));
+    pIter(p);
+  } while (p != NULL);
+
+  if (ll < 0)
+    ll = l;
+  else
+    ll = pLength(p);
+
+  if (q != &rp)
+    last = q;
+  pNext(q) = NULL;
+
+  p_Test(pNext(&rp), ri);
+  return pNext(&rp);
+}
+
+
Index: kernel/pp_Mult_mm__T.cc
===================================================================
--- kernel/pp_Mult_mm__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/pp_Mult_mm__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,54 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pp_Mult_mm__Template.cc
+ *  Purpose: template for p_Mult_n
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: pp_Mult_mm__T.cc,v 1.1.1.1 2003-10-06 12:16:02 Singular Exp $
+ *******************************************************************/
+
+/***************************************************************
+ *
+ *   Returns:  p*m
+ *   Const:    p, m
+ *
+ ***************************************************************/
+LINKAGE poly pp_Mult_mm(poly p, const poly m, const ring ri, poly &last)
+{
+  p_Test(p, ri);
+  p_LmTest(m, ri);
+  if (p == NULL)
+  {
+    last = NULL;
+    return NULL;
+  }
+  spolyrec rp;
+  poly q = &rp, r;
+  number ln = pGetCoeff(m);
+  omBin bin = ri->PolyBin;
+  DECLARE_LENGTH(const unsigned long length = ri->ExpL_Size);
+  const unsigned long* m_e = m->exp;
+  pAssume(!n_IsZero(ln,ri));
+  pAssume1(p_GetComp(m, ri) == 0 || p_MaxComp(p, ri) == 0);
+
+
+  do
+  {
+    p_AllocBin( pNext(q), bin, ri);
+    q = pNext(q);
+    pSetCoeff0(q, n_Mult(ln, pGetCoeff(p), ri));
+    p_MemSum(q->exp, p->exp, m_e, length);
+    p_MemAddAdjust(q, ri);
+    p = pNext(p);
+  }
+  while (p != NULL);
+  last = q;
+  pNext(q) = NULL;
+
+  p_Test(pNext(&rp), ri);
+  return pNext(&rp);
+}
+
+
Index: kernel/pp_Mult_nn__T.cc
===================================================================
--- kernel/pp_Mult_nn__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/pp_Mult_nn__T.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,44 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    pp_Mult_nn__Template.cc
+ *  Purpose: template for pp_Mult_nn
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 8/00
+ *  Version: $Id: pp_Mult_nn__T.cc,v 1.1.1.1 2003-10-06 12:16:02 Singular Exp $
+ *******************************************************************/
+
+/***************************************************************
+ *
+ *   Returns:  p*n
+ *   Const:    p, n
+ *
+ ***************************************************************/
+LINKAGE poly pp_Mult_nn(poly p, const number n, const ring r)
+{
+  pAssume(!n_IsZero(n,r));
+  p_Test(p, r);
+  if (p == NULL) return NULL;
+  spolyrec rp;
+  poly q = &rp;
+  omBin bin = r->PolyBin;
+  DECLARE_LENGTH(const unsigned long length = r->ExpL_Size);
+
+  do
+  {
+    p_AllocBin(pNext(q), bin, r);
+    q = pNext(q);
+    number nc = pGetCoeff(p);
+    pSetCoeff0(q, n_Mult(n, nc, r));
+    p_MemCopy(q->exp, p->exp, length);
+    pIter(p);
+  }
+  while (p != NULL);
+  pNext(q) = NULL;
+
+  p_Test(rp.next, r);
+  return rp.next;
+}
+
+
Index: kernel/prCopy.cc
===================================================================
--- kernel/prCopy.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/prCopy.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,237 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: prCopy.cc,v 1.1.1.1 2003-10-06 12:15:57 Singular Exp $ */
+/*
+* ABSTRACT - implementation of functions for Copy/Move/Delete for Polys
+*/
+
+#include "mod2.h"
+#include "omalloc.h"
+#include "p_polys.h"
+#include "numbers.h"
+#include "structs.h"
+#include "ring.h"
+#include "ideals.h"
+#include "sbuckets.h"
+
+static inline void
+prCopyEvector(poly dest, ring dest_r, poly src, ring src_r,int max)
+{
+  number n = pGetCoeff(dest);
+  int i;
+  for (i=max; i>0; i--)
+  {
+    p_SetExp(dest, i, p_GetExp( src, i,src_r), dest_r);
+    assume(n == pGetCoeff(dest));
+  }
+  if (rRing_has_Comp(dest_r))
+    p_SetComp(dest, p_GetComp( src,src_r), dest_r);
+  assume(n == pGetCoeff(dest));
+  p_Setm(dest, dest_r);
+  assume(n == pGetCoeff(dest));
+}
+
+#include "prCopy.inc"
+
+/////////////////////////////////////////////////////////////////////////
+// prCopy
+poly prCopy(poly p, ring dest_r)
+{
+  poly res;
+  if (rField_has_simple_Alloc(dest_r))
+    res = pr_Copy_REqual_NSimple_NoSort(p, dest_r, dest_r);
+  else
+    res = pr_Copy_REqual_NoNSimple_NoSort(p, dest_r, dest_r);
+  p_Test(res, dest_r);
+  return res;
+}
+
+poly prCopyR(poly p, ring src_r, ring dest_r)
+{
+  poly res;
+  if (rField_has_simple_Alloc(dest_r))
+    res =  pr_Copy_NoREqual_NSimple_Sort(p, src_r, dest_r);
+  else
+    res =  pr_Copy_NoREqual_NoNSimple_Sort(p, src_r, dest_r);
+  p_Test(res, dest_r);
+  return res;
+}
+
+poly prCopyR_NoSort(poly p, ring src_r, ring dest_r)
+{
+  poly res;
+  if (rField_has_simple_Alloc(dest_r))
+    res =  pr_Copy_NoREqual_NSimple_NoSort(p, src_r, dest_r);
+  else
+    res =  pr_Copy_NoREqual_NoNSimple_NoSort(p, src_r, dest_r);
+  p_Test(res, dest_r);
+  return res;
+}
+
+/////////////////////////////////////////////////////////////////////////
+// prMove
+poly prMoveR(poly &p, ring src_r, ring dest_r)
+{
+  poly res;
+  if (rField_has_simple_Alloc(dest_r))
+    res =  pr_Move_NoREqual_NSimple_Sort(p, src_r, dest_r);
+  else
+    res =  pr_Move_NoREqual_NoNSimple_Sort(p, src_r, dest_r);
+  p_Test(res, dest_r);
+  return res;
+}
+
+poly prMoveR_NoSort(poly &p, ring src_r, ring dest_r)
+{
+  poly res;
+  if (rField_has_simple_Alloc(dest_r))
+    res =  pr_Move_NoREqual_NSimple_NoSort(p, src_r, dest_r);
+  else
+    res =  pr_Move_NoREqual_NoNSimple_NoSort(p, src_r, dest_r);
+  p_Test(res, dest_r);  
+  return res;
+}
+
+poly prShallowCopyR_NoSort(poly p, ring r, ring dest_r)
+{
+  return pr_Copy_NoREqual_NSimple_NoSort(p, r, dest_r);
+}
+
+poly prShallowCopyR(poly p, ring r, ring dest_r = currRing)
+{
+  return pr_Copy_NoREqual_NSimple_Sort(p, r, dest_r);
+}
+
+/////////////////////////////////////////////////////////////////////////
+// prHead
+typedef poly (*prCopyProc_t)(poly &src_p, ring src_r, ring dest_r);
+
+poly prHeadR(poly p, ring src_r, ring dest_r, prCopyProc_t prproc)
+{
+  if (p == NULL) return NULL;
+  poly tail, head, q = p;
+  tail = pNext(p);
+  pNext(p) = NULL;
+  head = prproc(q, src_r, dest_r);
+  pNext(p) = tail;
+  return head;
+}
+
+poly prHeadR(poly p, ring src_r, ring dest_r)
+{
+  prCopyProc_t prproc;
+  if (rField_has_simple_Alloc(dest_r)) 
+    prproc = pr_Copy_NoREqual_NSimple_NoSort;
+  else
+    prproc = pr_Copy_NoREqual_NoNSimple_NoSort;  
+  
+  return prHeadR(p, src_r, dest_r, prproc);
+}
+
+/////////////////////////////////////////////////////////////////////////
+// idrCopy
+static inline ideal
+idrCopy(ideal id, ring src_r, ring dest_r, prCopyProc_t prproc)
+{
+  if (id == NULL) return NULL;
+  poly p;
+  ideal res = idInit(IDELEMS(id), id->rank);
+  int i;
+
+  for (i=IDELEMS(id)-1; i>=0; i--)
+  {
+    p = id->m[i];
+    res->m[i] = prproc(p, src_r, dest_r);
+    p_Test(res->m[i], dest_r);
+  }
+  return res;
+}
+
+ideal idrCopy(ideal id, ring dest_r)
+{
+  ideal res;
+  prCopyProc_t prproc;
+  if (rField_has_simple_Alloc(dest_r)) 
+    prproc = pr_Copy_REqual_NSimple_NoSort;
+  else
+    prproc = pr_Copy_REqual_NoNSimple_NoSort;
+  res =  idrCopy(id, dest_r, dest_r, prproc);
+  return res;
+}
+
+ideal idrCopyR(ideal id, ring src_r, ring dest_r)
+{
+  ideal res;
+  prCopyProc_t prproc;
+  if (rField_has_simple_Alloc(dest_r)) 
+    prproc = pr_Copy_NoREqual_NSimple_Sort;
+  else
+    prproc = pr_Copy_NoREqual_NoNSimple_Sort;
+  res =  idrCopy(id, src_r, dest_r, prproc);
+  return res;
+}
+  
+ideal idrCopyR_NoSort(ideal id, ring src_r, ring dest_r)
+{
+  ideal res;
+  prCopyProc_t prproc;
+  if (rField_has_simple_Alloc(dest_r)) 
+    prproc = pr_Copy_NoREqual_NSimple_NoSort;
+  else
+    prproc = pr_Copy_NoREqual_NoNSimple_NoSort;
+  res =  idrCopy(id, src_r, dest_r, prproc);
+  return res;
+}
+
+/////////////////////////////////////////////////////////////////////////
+// idrShallowCopy
+ideal idrShallowCopyR(ideal id, ring src_r, ring dest_r)
+{
+  return idrCopy(id, src_r, dest_r, pr_Copy_NoREqual_NSimple_Sort);
+}
+  
+ideal idrShallowCopyR_NoSort(ideal id, ring src_r, ring dest_r)
+{
+  return idrCopy(id, src_r, dest_r, pr_Copy_NoREqual_NSimple_NoSort);
+}
+  
+/////////////////////////////////////////////////////////////////////////
+// idrMove
+static inline ideal
+idrMove(ideal &id, ring src_r, ring dest_r, prCopyProc_t prproc)
+{
+  if (id == NULL) return NULL;
+  ideal res = id;
+
+  int i;
+  for (i=IDELEMS(id)-1; i>=0; i--)
+    res->m[i] = prproc(id->m[i], src_r, dest_r);
+  id = NULL;
+  return res;
+}
+
+ideal idrMoveR(ideal &id, ring src_r, ring dest_r)
+{
+  prCopyProc_t prproc;
+  ideal res;
+  if (rField_has_simple_Alloc(dest_r)) 
+    prproc = pr_Move_NoREqual_NSimple_Sort;
+  else
+    prproc = pr_Move_NoREqual_NoNSimple_Sort;
+  res =  idrMove(id, src_r, dest_r, prproc);
+  return res;
+}
+  
+ideal idrMoveR_NoSort(ideal &id, ring src_r, ring dest_r)
+{
+  prCopyProc_t prproc;
+  ideal res;
+  if (rField_has_simple_Alloc(dest_r)) 
+    prproc = pr_Move_NoREqual_NSimple_NoSort;
+  else
+    prproc = pr_Move_NoREqual_NoNSimple_NoSort;
+  res =  idrMove(id, src_r, dest_r, prproc);
+  return res;
+}
+
Index: kernel/prCopy.h
===================================================================
--- kernel/prCopy.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/prCopy.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,39 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: prCopy.h,v 1.1.1.1 2003-10-06 12:16:02 Singular Exp $ */
+/*
+* ABSTRACT - declarations of functions for Copy/Move/Delete for Polys
+*/
+
+
+/*************************************************************************
+ *
+ * MoveR, CopyR, ShallowCopyR: operations to get ideals/polys
+ *                             from source_r to dest_r where
+ *  - Coeff(source_r) == Coeff(dest_r)
+ *  - dest_r->N <= source_r->N
+ * Move:        input is destroyed
+ * ShallowCopy: monomials are copied, coeffs are set
+ * Copy:        monomials and coeffs are copied
+ *
+ ************************************************************************/
+poly prMoveR_NoSort(poly &p, ring r, ring dest_r = currRing);
+poly prMoveR(poly &p, ring r, ring dest_r = currRing);
+poly prCopyR_NoSort(poly p, ring r, ring dest_r = currRing);
+poly prCopyR(poly p, ring r, ring dest_r = currRing);
+poly prShallowCopyR_NoSort(poly p, ring r, ring dest_t = currRing);
+poly prShallowCopyR(poly p, ring r, ring dest_t = currRing);
+poly prHeadR(poly p, ring r, ring dest_r = currRing);
+
+ideal idrMoveR_NoSort(ideal &id, ring r, ring dest_r = currRing);
+ideal idrMoveR(ideal &id, ring r, ring dest_r = currRing);
+ideal idrCopyR_NoSort(ideal id, ring r, ring dest_r = currRing);
+ideal idrCopyR(ideal id, ring r, ring dest_r = currRing);
+ideal idrShallowCopyR_NoSort(ideal id, ring r, ring dest_r = currRing);
+ideal idrShallowCopyR(ideal id, ring r, ring dest_r = currRing);
+ideal idrHeadR(ideal id, ring r, ring dest_r = currRing);
+
+
+
+
Index: kernel/prCopy.pl
===================================================================
--- kernel/prCopy.pl	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/prCopy.pl	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,38 @@
+#!/usr/bin/perl
+# generate prCopy.inc
+
+@defines = ("PR_DELETE_SRC",  "Move", "Copy",
+            "PR_RING_EQUAL",   "REqual", "NoREqual",
+            "PR_NUMBER_SIMPLE", "NSimple", "NoNSimple", 
+            "PR_NO_SORT", "NoSort", "Sort");
+
+@def = ("Move", "REqual", "NSimple", "NoSort");
+@notdef = ("Copy", "NoREqaul", "NoNSimple", "Sort");
+
+sub Generate
+{
+  my ($prefix, @args) = @_;
+
+  if (@args)
+  {
+    my $name = shift @args;
+    my $yes = shift @args;
+    my $no = shift @args;
+    print "#undef $name\n";
+    print "#define $name 0\n";
+    Generate($prefix."_".$no, @args);
+    print "#undef $name\n";
+    print "#define $name 1\n";
+    Generate($prefix."_".$yes, @args);
+  }
+  else
+  {
+    print "#undef PR_NAME\n";
+    print "#define PR_NAME $prefix\n";
+    print "#include \"prCopyMacros.h\"\n";
+    print "#include \"prCopyTemplate.cc\"\n";
+  }
+  print "\n";
+}
+
+Generate("pr", @defines);
Index: kernel/prCopyMacros.h
===================================================================
--- kernel/prCopyMacros.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/prCopyMacros.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,50 @@
+#undef PR_DELETE_MONOM
+#if PR_DELETE_SRC > 0
+#define PR_DELETE_MONOM(src, r_src)             \
+do                                              \
+{                                               \
+  PR_NDELETE(&pGetCoeff(src), r_src);           \
+  p_LmFree(src, r_src);            \
+}                                               \
+while (0)
+#else
+#define PR_DELETE_MONOM(src, r_src) ((void)0)
+#endif
+
+#undef PR_INIT_EVECTOR_COPY
+#undef PR_CPY_EVECTOR
+#undef PR_ALLOC_MONOM
+#if PR_RING_EQUAL > 0
+#undef PR_NO_SORT
+#define PR_NO_SORT 1
+#define PR_INIT_EVECTOR_COPY(r_src, r_dest) ((void)0)
+#define PR_CPY_EVECTOR(dest, dest_r, src, src_r) \
+  omMemcpyW(dest->exp, src->exp, dest_r->ExpL_Size)
+#define PR_ALLOC_MONOM(r) p_New(r) 
+#else
+#define  PR_INIT_EVECTOR_COPY(r_src, r_dest) int _min = si_min(r_dest->N, r_src->N)
+#define  PR_CPY_EVECTOR(dest, dest_r, src, src_r) \
+  prCopyEvector(dest, dest_r, src, src_r, _min)
+#define PR_ALLOC_MONOM(r) p_Init(r) 
+#endif
+
+#undef PR_NCOPY
+#undef PR_NDELETE
+#undef PR_NUMBER_SIMPLE_NAME
+#if PR_NUMBER_SIMPLE > 0
+#define PR_NCOPY(n, r) n
+#define PR_NDELETE(n, r) ((void)0)
+#define PR_NUMBER_SIMPLE_NAME NSimple
+#else
+#define PR_NCOPY(n, r) n_Copy(n,r)
+#define PR_NDELETE(n, r) n_Delete(n,r)
+#define PR_NUMBER_SIMPLE_NAME NoNSimple
+#endif
+
+#undef PR_SORT_POLY
+#if PR_NO_SORT > 0
+#define PR_SORT_POLY(p, d_r, s_r) ((void)0)
+#else
+#define PR_SORT_POLY(p, d_r, s_r) p = p_SortMerge(p, d_r, d_r->OrdSgn == s_r->OrdSgn)
+#endif
+
Index: kernel/prCopyTemplate.cc
===================================================================
--- kernel/prCopyTemplate.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/prCopyTemplate.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,33 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: prCopyTemplate.cc,v 1.1.1.1 2003-10-06 12:16:02 Singular Exp $ */
+/*
+* ABSTRACT - templates for pr routines
+*/
+
+
+static poly PR_NAME
+(poly &src, ring r_src, ring r_dest)
+{
+  spolyrec dest_s;
+  poly dest = &dest_s;
+  poly tmp;
+  PR_INIT_EVECTOR_COPY(r_src, r_dest);
+
+  while (src != NULL)
+  {
+    pNext(dest) = (poly) PR_ALLOC_MONOM(r_dest);
+    pIter(dest);
+    pSetCoeff0(dest, PR_NCOPY(pGetCoeff(src), r_src));
+    PR_CPY_EVECTOR(dest, r_dest, src, r_src);
+    tmp = pNext(src);
+    PR_DELETE_MONOM(src, r_src);
+    src = tmp;
+  }
+  pNext(dest) = NULL;
+  dest = pNext(&dest_s);
+  PR_SORT_POLY(dest, r_dest, r_src);
+  p_Test(dest, r_dest);
+  return dest;
+}
Index: kernel/ring.cc
===================================================================
--- kernel/ring.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/ring.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,3863 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: ring.cc,v 1.1.1.1 2003-10-06 12:15:55 Singular Exp $ */
+
+/*
+* ABSTRACT - the interpreter related ring operations
+*/
+
+/* includes */
+#include <math.h>
+#include "mod2.h"
+#include "structs.h"
+#include "omalloc.h"
+#include "polys.h"
+#include "numbers.h"
+#include "febase.h"
+#include "ipconv.h"
+#include "intvec.h"
+#include "longalg.h"
+#include "ffields.h"
+#include "ideals.h"
+#include "ring.h"
+#include "prCopy.h"
+#include "../Singular/ipshell.h"
+#include "p_Procs.h"
+#ifdef HAVE_PLURAL
+#include "gring.h"
+#include "matpol.h"
+#endif
+
+#define BITS_PER_LONG 8*SIZEOF_LONG
+
+static const char * const ringorder_name[] =
+{
+  " ?", //ringorder_no = 0,
+  "a", //ringorder_a,
+  "c", //ringorder_c,
+  "C", //ringorder_C,
+  "M", //ringorder_M,
+  "S", //ringorder_S,
+  "s", //ringorder_s,
+  "lp", //ringorder_lp,
+  "dp", //ringorder_dp,
+  "rp", //ringorder_rp,
+  "Dp", //ringorder_Dp,
+  "wp", //ringorder_wp,
+  "Wp", //ringorder_Wp,
+  "ls", //ringorder_ls,
+  "ds", //ringorder_ds,
+  "Ds", //ringorder_Ds,
+  "ws", //ringorder_ws,
+  "Ws", //ringorder_Ws,
+  "L", //ringorder_L,
+  "aa", //ringorder_aa
+  " _" //ringorder_unspec
+};
+
+const char * rSimpleOrdStr(int ord)
+{
+  return ringorder_name[ord];
+}
+
+// unconditionally deletes fields in r
+static void rDelete(ring r);
+// set r->VarL_Size, r->VarL_Offset, r->VarL_LowIndex
+static void rSetVarL(ring r);
+// get r->divmask depending on bits per exponent
+static unsigned long rGetDivMask(int bits);
+// right-adjust r->VarOffset
+static void rRightAdjustVarOffset(ring r);
+static void rOptimizeLDeg(ring r);
+
+/*0 implementation*/
+//BOOLEAN rField_is_R(ring r=currRing)
+//{
+//  if (r->ch== -1)
+//  {
+//    if (r->float_len==(short)0) return TRUE;
+//  }
+//  return FALSE;
+//}
+
+// internally changes the gloabl ring and resets the relevant
+// global variables:
+// complete == FALSE : only delete operations are enabled
+// complete == TRUE  : full reset of all variables
+void rChangeCurrRing(ring r)
+{
+  /*------------ set global ring vars --------------------------------*/
+  currRing = r;
+  currQuotient=NULL;
+  if (r != NULL)
+  {
+    rTest(r);
+    /*------------ set global ring vars --------------------------------*/
+    currQuotient=r->qideal;
+
+    /*------------ global variables related to coefficients ------------*/
+    nSetChar(r);
+
+    /*------------ global variables related to polys -------------------*/
+    pSetGlobals(r);
+  }
+}
+
+void rSetHdl(idhdl h)
+{
+  int i;
+  ring rg = NULL;
+  if (h!=NULL)
+  {
+//   Print(" new ring:%s (l:%d)\n",IDID(h),IDLEV(h));
+    rg = IDRING(h);
+    omCheckAddrSize((ADDRESS)h,sizeof(idrec));
+    if (IDID(h))  // OB: ????
+      omCheckAddr((ADDRESS)IDID(h));
+    rTest(rg);
+  }
+
+  // clean up history
+  if (sLastPrinted.RingDependend())
+  {
+    sLastPrinted.CleanUp();
+    memset(&sLastPrinted,0,sizeof(sleftv));
+  }
+
+   /*------------ change the global ring -----------------------*/
+  rChangeCurrRing(rg);
+  currRingHdl = h;
+}
+
+ring rDefault(int ch, int N, char **n)
+{
+  ring r=(ring) omAlloc0Bin(sip_sring_bin);
+  r->ch    = ch;
+  r->N     = N;
+  /*r->P     = 0; Alloc0 */
+  /*names*/
+  r->names = (char **) omAlloc0(N * sizeof(char_ptr));
+  int i;
+  for(i=0;i<N;i++)
+  {
+    r->names[i]  = omStrDup(n[i]);
+  }
+  /*weights: entries for 2 blocks: NULL*/
+  r->wvhdl = (int **)omAlloc0(2 * sizeof(int_ptr));
+  /*order: lp,0*/
+  r->order = (int *) omAlloc(2* sizeof(int *));
+  r->block0 = (int *)omAlloc0(2 * sizeof(int *));
+  r->block1 = (int *)omAlloc0(2 * sizeof(int *));
+  /* ringorder dp for the first block: var 1..N */
+  r->order[0]  = ringorder_lp;
+  r->block0[0] = 1;
+  r->block1[0] = N;
+  /* the last block: everything is 0 */
+  r->order[1]  = 0;
+  /*polynomial ring*/
+  r->OrdSgn    = 1;
+
+  /* complete ring intializations */
+  rComplete(r);
+  return r;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// rInit: define a new ring from sleftv's
+//
+
+/////////////////////////////
+// Auxillary functions
+//
+
+// check intvec, describing the ordering
+static BOOLEAN rCheckIV(intvec *iv)
+{
+  if ((iv->length()!=2)&&(iv->length()!=3))
+  {
+    WerrorS("weights only for orderings wp,ws,Wp,Ws,a,M");
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static int rTypeOfMatrixOrder(intvec * order)
+{
+  int i=0,j,typ=1;
+  int sz = (int)sqrt((double)(order->length()-2));
+
+  while ((i<sz) && (typ==1))
+  {
+    j=0;
+    while ((j<sz) && ((*order)[j*sz+i+2]==0)) j++;
+    if (j>=sz)
+    {
+      typ = 0;
+      WerrorS("Matrix order not complete");
+    }
+    else if ((*order)[j*sz+i+2]<0)
+      typ = -1;
+    else
+      i++;
+  }
+  return typ;
+}
+
+// set R->order, R->block, R->wvhdl, r->OrdSgn from sleftv
+static BOOLEAN rSleftvOrdering2Ordering(sleftv *ord, ring R)
+{
+  int last = 0, o=0, n = 1, i=0, typ = 1, j;
+  sleftv *sl = ord;
+
+  // determine nBlocks
+  while (sl!=NULL)
+  {
+    intvec *iv = (intvec *)(sl->data);
+    if (((*iv)[1]==ringorder_c)||((*iv)[1]==ringorder_C)) i++;
+    else if ((*iv)[1]==ringorder_L)
+    {
+      R->bitmask=(*iv)[2];
+      n--;
+    }
+    else if ((*iv)[1]!=ringorder_a) o++;
+    n++;
+    sl=sl->next;
+  }
+  // check whether at least one real ordering
+  if (o==0)
+  {
+    WerrorS("invalid combination of orderings");
+    return TRUE;
+  }
+  // if no c/C ordering is given, increment n
+  if (i==0) n++;
+  else if (i != 1)
+  {
+    // throw error if more than one is given
+    WerrorS("more than one ordering c/C specified");
+    return TRUE;
+  }
+
+  // initialize fields of R
+  R->order=(int *)omAlloc0(n*sizeof(int));
+  R->block0=(int *)omAlloc0(n*sizeof(int));
+  R->block1=(int *)omAlloc0(n*sizeof(int));
+  R->wvhdl=(int**)omAlloc0(n*sizeof(int_ptr));
+
+  // init order, so that rBlocks works correctly
+  for (j=0; j < n-1; j++)
+    R->order[j] = (int) ringorder_unspec;
+  // set last _C order, if no c/C order was given
+  if (i == 0) R->order[n-2] = ringorder_C;
+
+  /* init orders */
+  sl=ord;
+  n=-1;
+  while (sl!=NULL)
+  {
+    intvec *iv;
+    iv = (intvec *)(sl->data);
+    if ((*iv)[1]!=ringorder_L)
+    {
+      n++;
+
+      /* the format of an ordering:
+       *  iv[0]: factor
+       *  iv[1]: ordering
+       *  iv[2..end]: weights
+       */
+      R->order[n] = (*iv)[1];
+      switch ((*iv)[1])
+      {
+          case ringorder_ws:
+          case ringorder_Ws:
+            typ=-1;
+          case ringorder_wp:
+          case ringorder_Wp:
+            R->wvhdl[n]=(int*)omAlloc((iv->length()-1)*sizeof(int));
+            for (i=2; i<iv->length(); i++)
+              R->wvhdl[n][i-2] = (*iv)[i];
+            R->block0[n] = last+1;
+            last += iv->length()-2;
+            R->block1[n] = last;
+            break;
+          case ringorder_ls:
+          case ringorder_ds:
+          case ringorder_Ds:
+            typ=-1;
+          case ringorder_lp:
+          case ringorder_dp:
+          case ringorder_Dp:
+          case ringorder_rp:
+            R->block0[n] = last+1;
+            if (iv->length() == 3) last+=(*iv)[2];
+            else last += (*iv)[0];
+            R->block1[n] = last;
+            if (rCheckIV(iv)) return TRUE;
+            break;
+          case ringorder_S:
+          case ringorder_c:
+          case ringorder_C:
+            if (rCheckIV(iv)) return TRUE;
+            break;
+          case ringorder_aa:
+          case ringorder_a:
+            R->block0[n] = last+1;
+            R->block1[n] = min(last+iv->length()-2 , R->N);
+            R->wvhdl[n] = (int*)omAlloc((iv->length()-1)*sizeof(int));
+            for (i=2; i<iv->length(); i++)
+            {
+              R->wvhdl[n][i-2]=(*iv)[i];
+              if ((*iv)[i]<0) typ=-1;
+            }
+            break;
+          case ringorder_M:
+          {
+            int Mtyp=rTypeOfMatrixOrder(iv);
+            if (Mtyp==0) return TRUE;
+            if (Mtyp==-1) typ = -1;
+
+            R->wvhdl[n] =( int *)omAlloc((iv->length()-1)*sizeof(int));
+            for (i=2; i<iv->length();i++)
+              R->wvhdl[n][i-2]=(*iv)[i];
+
+            R->block0[n] = last+1;
+            last += (int)sqrt((double)(iv->length()-2));
+            R->block1[n] = last;
+            break;
+          }
+
+          case ringorder_no:
+            R->order[n] = ringorder_unspec;
+            return TRUE;
+
+          default:
+            Werror("Internal Error: Unknown ordering %d", (*iv)[1]);
+            R->order[n] = ringorder_unspec;
+            return TRUE;
+      }
+    }
+    sl=sl->next;
+  }
+
+  // check for complete coverage
+  if ((R->order[n]==ringorder_c) ||  (R->order[n]==ringorder_C)) n--;
+  if (R->block1[n] != R->N)
+  {
+    if (((R->order[n]==ringorder_dp) ||
+         (R->order[n]==ringorder_ds) ||
+         (R->order[n]==ringorder_Dp) ||
+         (R->order[n]==ringorder_Ds) ||
+         (R->order[n]==ringorder_rp) ||
+         (R->order[n]==ringorder_lp) ||
+         (R->order[n]==ringorder_ls))
+        &&
+        R->block0[n] <= R->N)
+    {
+      R->block1[n] = R->N;
+    }
+    else
+    {
+      Werror("mismatch of number of vars (%d) and ordering (%d vars)",
+             R->N,R->block1[n]);
+      return TRUE;
+    }
+  }
+  R->OrdSgn = typ;
+  return FALSE;
+}
+
+// get array of strings from list of sleftv's
+static BOOLEAN rSleftvList2StringArray(sleftv* sl, char** p)
+{
+
+  while(sl!=NULL)
+  {
+    if (sl->Name() == sNoName)
+    {
+      if (sl->Typ()==POLY_CMD)
+      {
+        sleftv s_sl;
+        iiConvert(POLY_CMD,ANY_TYPE,-1,sl,&s_sl);
+        if (s_sl.Name() != sNoName)
+          *p = omStrDup(s_sl.Name());
+        else
+          *p = NULL;
+        sl->next = s_sl.next;
+        s_sl.next = NULL;
+        s_sl.CleanUp();
+        if (*p == NULL) return TRUE;
+      }
+      else
+        return TRUE;
+    }
+    else
+      *p = omStrDup(sl->Name());
+    p++;
+    sl=sl->next;
+  }
+  return FALSE;
+}
+
+
+////////////////////
+//
+// rInit itself:
+//
+// INPUT:  s: name, pn: ch & parameter (names), rv: variable (names)
+//         ord: ordering
+// RETURN: currRingHdl on success
+//         NULL        on error
+// NOTE:   * makes new ring to current ring, on success
+//         * considers input sleftv's as read-only
+//idhdl rInit(char *s, sleftv* pn, sleftv* rv, sleftv* ord)
+ring rInit(sleftv* pn, sleftv* rv, sleftv* ord)
+{
+  int ch;
+  int float_len=0;
+  int float_len2=0;
+  ring R = NULL;
+  idhdl tmp = NULL;
+  BOOLEAN ffChar=FALSE;
+  int typ = 1;
+
+  /* ch -------------------------------------------------------*/
+  // get ch of ground field
+  int numberOfAllocatedBlocks;
+
+  if (pn->Typ()==INT_CMD)
+  {
+    ch=(int)pn->Data();
+  }
+  else if ((pn->name != NULL)
+  && ((strcmp(pn->name,"real")==0) || (strcmp(pn->name,"complex")==0)))
+  {
+    BOOLEAN complex_flag=(strcmp(pn->name,"complex")==0);
+    ch=-1;
+    if ((pn->next!=NULL) && (pn->next->Typ()==INT_CMD))
+    {
+      float_len=(int)pn->next->Data();
+      float_len2=float_len;
+      pn=pn->next;
+      if ((pn->next!=NULL) && (pn->next->Typ()==INT_CMD))
+      {
+        float_len2=(int)pn->next->Data();
+        pn=pn->next;
+      }
+    }
+    if ((pn->next==NULL) && complex_flag)
+    {
+      pn->next=(leftv)omAlloc0Bin(sleftv_bin);
+      pn->next->name=omStrDup("i");
+    }
+  }
+  else
+  {
+    Werror("Wrong ground field specification");
+    goto rInitError;
+  }
+  pn=pn->next;
+
+  int l, last;
+  sleftv * sl;
+  /*every entry in the new ring is initialized to 0*/
+
+  /* characteristic -----------------------------------------------*/
+  /* input: 0 ch=0 : Q     parameter=NULL    ffChar=FALSE   float_len
+   *         0    1 : Q(a,...)        *names         FALSE
+   *         0   -1 : R               NULL           FALSE  0
+   *         0   -1 : R               NULL           FALSE  prec. >6
+   *         0   -1 : C               *names         FALSE  prec. 0..?
+   *         p    p : Fp              NULL           FALSE
+   *         p   -p : Fp(a)           *names         FALSE
+   *         q    q : GF(q=p^n)       *names         TRUE
+  */
+  if (ch!=-1)
+  {
+    int l = 0;
+
+    if (ch!=0 && (ch<2)
+    #ifndef NV_OPS
+    || (ch > 32003)
+    #endif
+    )
+    {
+      Warn("%d is invalid characteristic of ground field. 32003 is used.", ch);
+      ch=32003;
+    }
+    // load fftable, if necessary
+    if (pn!=NULL)
+    {
+      while ((ch!=fftable[l]) && (fftable[l])) l++;
+      if (fftable[l]==0) ch = IsPrime(ch);
+      else
+      {
+        char *m[1]={(char *)sNoName};
+        nfSetChar(ch,m);
+        if (errorreported) goto rInitError;
+        else ffChar=TRUE;
+      }
+    }
+    else
+      ch = IsPrime(ch);
+  }
+  // allocated ring and set ch
+  R = (ring) omAlloc0Bin(sip_sring_bin);
+  R->ch = ch;
+  if (ch == -1)
+  {
+    R->float_len= min(float_len,32767);
+    R->float_len2= min(float_len2,32767);
+  }
+
+  /* parameter -------------------------------------------------------*/
+  if (pn!=NULL)
+  {
+    R->P=pn->listLength();
+    //if ((ffChar|| (ch == 1)) && (R->P > 1))
+    if ((R->P > 1) && (ffChar || (ch == -1)))
+    {
+      WerrorS("too many parameters");
+      goto rInitError;
+    }
+    R->parameter=(char**)omAlloc0(R->P*sizeof(char_ptr));
+    if (rSleftvList2StringArray(pn, R->parameter))
+    {
+      WerrorS("parameter expected");
+      goto rInitError;
+    }
+    if (ch>1 && !ffChar) R->ch=-ch;
+    else if (ch==0) R->ch=1;
+  }
+  else if (ffChar)
+  {
+    WerrorS("need one parameter");
+    goto rInitError;
+  }
+  /* post-processing of field description */
+  // we have short reals, but no short complex
+  if ((R->ch == - 1)
+  && (R->parameter !=NULL)
+  && (R->float_len < SHORT_REAL_LENGTH))
+  {
+    R->float_len = SHORT_REAL_LENGTH;
+    R->float_len2 = SHORT_REAL_LENGTH;
+  }
+
+  /* names and number of variables-------------------------------------*/
+  {
+    int l=rv->listLength();
+#if SIZEOF_SHORT == 2
+#define MAX_SHORT 0x7fff
+#endif
+    if (l>MAX_SHORT)
+    {
+      Werror("too many ring variables(%d), max is %d",l,MAX_SHORT);
+       goto rInitError;
+    }
+    R->N = l; /*rv->listLength();*/
+  }
+  R->names   = (char **)omAlloc0(R->N * sizeof(char_ptr));
+  if (rSleftvList2StringArray(rv, R->names))
+  {
+    WerrorS("name of ring variable expected");
+    goto rInitError;
+  }
+
+  /* check names and parameters for conflicts ------------------------- */
+  {
+    int i,j;
+    for(i=0;i<R->P; i++)
+    {
+      for(j=0;j<R->N;j++)
+      {
+        if (strcmp(R->parameter[i],R->names[j])==0)
+        {
+          Werror("parameter %d conflicts with variable %d",i+1,j+1);
+          goto rInitError;
+        }
+      }
+    }
+  }
+  /* ordering -------------------------------------------------------------*/
+  if (rSleftvOrdering2Ordering(ord, R))
+    goto rInitError;
+
+  // Complete the initialization
+  if (rComplete(R,1))
+    goto rInitError;
+
+  rTest(R);
+
+  // try to enter the ring into the name list
+  // need to clean up sleftv here, before this ring can be set to
+  // new currRing or currRing can be killed beacuse new ring has
+  // same name
+  if (pn != NULL) pn->CleanUp();
+  if (rv != NULL) rv->CleanUp();
+  if (ord != NULL) ord->CleanUp();
+  //if ((tmp = enterid(s, myynest, RING_CMD, &IDROOT))==NULL)
+  //  goto rInitError;
+
+  //memcpy(IDRING(tmp),R,sizeof(*R));
+  // set current ring
+  //omFreeBin(R,  ip_sring_bin);
+  //return tmp;
+  return R;
+
+  // error case:
+  rInitError:
+  if  (R != NULL) rDelete(R);
+  if (pn != NULL) pn->CleanUp();
+  if (rv != NULL) rv->CleanUp();
+  if (ord != NULL) ord->CleanUp();
+  return NULL;
+}
+
+/*2
+ * set a new ring from the data:
+ s: name, chr: ch, varnames: rv, ordering: ord, typ: typ
+ */
+
+int r_IsRingVar(char *n, ring r)
+{
+  if ((r!=NULL) && (r->names!=NULL))
+  {
+    for (int i=0; i<r->N; i++)
+    {
+      if (r->names[i]==NULL) return -1;
+      if (strcmp(n,r->names[i]) == 0) return (int)i;
+    }
+  }
+  return -1;
+}
+
+
+void rWrite(ring r)
+{
+  if ((r==NULL)||(r->order==NULL))
+    return; /*to avoid printing after errors....*/
+
+  int nblocks=rBlocks(r);
+
+  // omCheckAddrSize(r,sizeof(ip_sring));
+  omCheckAddrSize(r->order,nblocks*sizeof(int));
+  omCheckAddrSize(r->block0,nblocks*sizeof(int));
+  omCheckAddrSize(r->block1,nblocks*sizeof(int));
+  omCheckAddrSize(r->wvhdl,nblocks*sizeof(int_ptr));
+  omCheckAddrSize(r->names,r->N*sizeof(char_ptr));
+
+  nblocks--;
+
+
+  if (rField_is_GF(r))
+  {
+    Print("//   # ground field : %d\n",rInternalChar(r));
+    Print("//   primitive element : %s\n", r->parameter[0]);
+    if (r==currRing)
+    {
+      StringSetS("//   minpoly        : ");
+      nfShowMipo();PrintS(StringAppendS("\n"));
+    }
+  }
+  else
+  {
+    PrintS("//   characteristic : ");
+    if ( rField_is_R(r) )             PrintS("0 (real)\n");  /* R */
+    else if ( rField_is_long_R(r) )
+      Print("0 (real:%d digits, additional %d digits)\n",
+             r->float_len,r->float_len2);  /* long R */
+    else if ( rField_is_long_C(r) )
+      Print("0 (complex:%d digits, additional %d digits)\n",
+             r->float_len, r->float_len2);  /* long C */
+    else
+      Print ("%d\n",rChar(r)); /* Fp(a) */
+    if (r->parameter!=NULL)
+    {
+      Print ("//   %d parameter    : ",rPar(r));
+      char **sp=r->parameter;
+      int nop=0;
+      while (nop<rPar(r))
+      {
+        PrintS(*sp);
+        PrintS(" ");
+        sp++; nop++;
+      }
+      PrintS("\n//   minpoly        : ");
+      if ( rField_is_long_C(r) )
+      {
+        // i^2+1:
+        Print("(%s^2+1)\n",r->parameter[0]);
+      }
+      else if (r->minpoly==NULL)
+      {
+        PrintS("0\n");
+      }
+      else if (r==currRing)
+      {
+        StringSetS(""); nWrite(r->minpoly); PrintS(StringAppendS("\n"));
+      }
+      else
+      {
+        PrintS("...\n");
+      }
+    }
+  }
+  Print("//   number of vars : %d",r->N);
+
+  //for (nblocks=0; r->order[nblocks]; nblocks++);
+  nblocks=rBlocks(r)-1;
+
+  for (int l=0, nlen=0 ; l<nblocks; l++)
+  {
+    int i;
+    Print("\n//        block %3d : ",l+1);
+
+    Print("ordering %s", rSimpleOrdStr(r->order[l]));
+
+    if ((r->order[l] >= ringorder_lp)
+    ||(r->order[l] == ringorder_M)
+    ||(r->order[l] == ringorder_a)
+    ||(r->order[l] == ringorder_aa))
+    {
+      PrintS("\n//                  : names    ");
+      for (i = r->block0[l]-1; i<r->block1[l]; i++)
+      {
+        nlen = strlen(r->names[i]);
+        Print("%s ",r->names[i]);
+      }
+    }
+#ifndef NDEBUG
+    else if (r->order[l] == ringorder_s)
+    {
+      Print("  syzcomp at %d",r->typ[l].data.syz.limit);
+    }
+#endif
+
+    if (r->wvhdl[l]!=NULL)
+    {
+      for (int j= 0;
+           j<(r->block1[l]-r->block0[l]+1)*(r->block1[l]-r->block0[l]+1);
+           j+=i)
+      {
+        PrintS("\n//                  : weights  ");
+        for (i = 0; i<=r->block1[l]-r->block0[l]; i++)
+        {
+          Print("%*d " ,nlen,r->wvhdl[l][i+j],i+j);
+        }
+        if (r->order[l]!=ringorder_M) break;
+      }
+    }
+  }
+#ifdef HAVE_PLURAL
+  if ((r->nc!=NULL) && (r==currRing))
+  {
+    poly pl=NULL;
+    int nl;
+    PrintS("\n//   noncommutative relations:");
+    //    Print("\n//   noncommutative relations (type %d):",(int)r->nc->type);
+    for (int i = 1; i<r->N; i++)
+    {
+      for (int j = i+1; j<=r->N; j++)
+      {
+        nl=nIsOne(p_GetCoeff(MATELEM(r->nc->C,i,j),r));
+        if ((MATELEM(r->nc->D,i,j)!=NULL)||(!nl))
+        {
+          Print("\n//    %s%s=",r->names[j-1],r->names[i-1]);
+          pl=MATELEM(r->nc->MT[UPMATELEM(i,j,r->N)],1,1);
+          pWrite0(pl);
+        }
+      }
+    }
+#ifdef PDEBUG
+    Print("\n//   noncommutative type:%d",r->nc->type);
+    Print("\n//   is skew constant:%d",r->nc->IsSkewConstant);
+#endif
+  }
+#endif
+  if (r->qideal!=NULL)
+  {
+    PrintS("\n// quotient ring from ideal");
+    if (r==currRing)
+    {
+      PrintLn();
+      iiWriteMatrix((matrix)r->qideal,"_",1);
+    }
+    else PrintS(" ...");
+  }
+}
+
+static void rDelete(ring r)
+{
+  int i, j;
+
+  if (r == NULL) return;
+
+  rUnComplete(r);
+  // delete order stuff
+  if (r->order != NULL)
+  {
+    i=rBlocks(r);
+    assume(r->block0 != NULL && r->block1 != NULL && r->wvhdl != NULL);
+    // delete order
+    omFreeSize((ADDRESS)r->order,i*sizeof(int));
+    omFreeSize((ADDRESS)r->block0,i*sizeof(int));
+    omFreeSize((ADDRESS)r->block1,i*sizeof(int));
+    // delete weights
+    for (j=0; j<i; j++)
+    {
+      if (r->wvhdl[j]!=NULL)
+        omFree(r->wvhdl[j]);
+    }
+    omFreeSize((ADDRESS)r->wvhdl,i*sizeof(short *));
+  }
+  else
+  {
+    assume(r->block0 == NULL && r->block1 == NULL && r->wvhdl == NULL);
+  }
+
+  // delete varnames
+  if(r->names!=NULL)
+  {
+    for (i=0; i<r->N; i++)
+    {
+      if (r->names[i] != NULL) omFree((ADDRESS)r->names[i]);
+    }
+    omFreeSize((ADDRESS)r->names,r->N*sizeof(char_ptr));
+  }
+
+  // delete parameter
+  if (r->parameter!=NULL)
+  {
+    char **s=r->parameter;
+    j = 0;
+    while (j < rPar(r))
+    {
+      if (*s != NULL) omFree((ADDRESS)*s);
+      s++;
+      j++;
+    }
+    omFreeSize((ADDRESS)r->parameter,rPar(r)*sizeof(char_ptr));
+  }
+  omFreeBin(r, ip_sring_bin);
+}
+
+void rKill(ring r)
+{
+  if ((r->ref<=0)&&(r->order!=NULL))
+  {
+#ifdef RDEBUG
+    if (traceit &TRACE_SHOW_RINGS) Print("kill ring %x\n",r);
+#endif
+    if (r==currRing)
+    {
+      if (r->qideal!=NULL)
+      {
+        idDelete(&r->qideal);
+        r->qideal=NULL;
+        currQuotient=NULL;
+      }
+      if (ppNoether!=NULL) pDelete(&ppNoether);
+      if (sLastPrinted.RingDependend())
+      {
+        sLastPrinted.CleanUp();
+      }
+      if ((myynest>0) && (iiRETURNEXPR[myynest].RingDependend()))
+      {
+        WerrorS("return value depends on local ring variable (export missing ?)");
+        iiRETURNEXPR[myynest].CleanUp();
+      }
+      currRing=NULL;
+      currRingHdl=NULL;
+    }
+    else if (r->qideal!=NULL)
+    {
+      id_Delete(&r->qideal, r);
+      r->qideal = NULL;
+    }
+    #ifdef HAVE_PLURAL
+    // delete noncommutative extension
+    if (r->nc!=NULL)
+    {
+      if (r->nc->ref>1) r->nc->ref--;
+      else ncKill(r);
+    }
+    #endif
+    nKillChar(r);
+    int i=1;
+    int j;
+    int *pi=r->order;
+#ifdef USE_IILOCALRING
+    for (j=0;j<iiRETURNEXPR_len;j++)
+    {
+      if (iiLocalRing[j]==r)
+      {
+        if (j<myynest) Warn("killing the basering for level %d",j);
+        iiLocalRing[j]=NULL;
+      }
+    }
+#else /* USE_IILOCALRING */
+//#endif /* USE_IILOCALRING */
+    {
+      proclevel * nshdl = procstack;
+      int lev=myynest-1;
+
+      for(; nshdl != NULL; nshdl = nshdl->next)
+      {
+        if (nshdl->cRing==r)
+        {
+          Warn("killing the basering for level %d",lev);
+          nshdl->cRing=NULL;
+          nshdl->cRingHdl=NULL;
+        }
+      }
+    }
+#endif /* USE_IILOCALRING */
+
+    rDelete(r);
+    return;
+  }
+  r->ref--;
+}
+
+void rKill(idhdl h)
+{
+  ring r = IDRING(h);
+  int ref=0;
+  if (r!=NULL)
+  {
+    ref=r->ref;
+    rKill(r);
+  }
+  if (h==currRingHdl)
+  {
+    if (ref<=0) { currRing=NULL; currRingHdl=NULL;}
+    else
+    {
+      currRingHdl=rFindHdl(r,currRingHdl,NULL);
+    }
+  }
+}
+
+idhdl rSimpleFindHdl(ring r, idhdl root, idhdl n=NULL)
+{
+  idhdl h=root;
+  while (h!=NULL)
+  {
+    if (((IDTYP(h)==RING_CMD)||(IDTYP(h)==QRING_CMD))
+    && (h!=n)
+    && (h->data.uring==r)
+    )
+      return h;
+    h=IDNEXT(h);
+  }
+  return NULL;
+}
+
+int rOrderName(char * ordername)
+{
+  int order=ringorder_unspec;
+  while (order!= 0)
+  {
+    if (strcmp(ordername,rSimpleOrdStr(order))==0)
+      break;
+    order--;
+  }
+  if (order==0) Werror("wrong ring order `%s`",ordername);
+  omFree((ADDRESS)ordername);
+  return order;
+}
+
+char * rOrdStr(ring r)
+{
+  int nblocks,l,i;
+
+  for (nblocks=0; r->order[nblocks]; nblocks++);
+  nblocks--;
+
+  StringSetS("");
+  for (l=0; ; l++)
+  {
+    StringAppend((char *)rSimpleOrdStr(r->order[l]));
+    if ((r->order[l] != ringorder_c) && (r->order[l] != ringorder_C))
+    {
+      if (r->wvhdl[l]!=NULL)
+      {
+        StringAppendS("(");
+        for (int j= 0;
+             j<(r->block1[l]-r->block0[l]+1)*(r->block1[l]-r->block0[l]+1);
+             j+=i+1)
+        {
+          char c=',';
+          for (i = 0; i<r->block1[l]-r->block0[l]; i++)
+          {
+            StringAppend("%d," ,r->wvhdl[l][i+j]);
+          }
+          if (r->order[l]!=ringorder_M)
+          {
+            StringAppend("%d)" ,r->wvhdl[l][i+j]);
+            break;
+          }
+          if (j+i+1==(r->block1[l]-r->block0[l]+1)*(r->block1[l]-r->block0[l]+1))
+            c=')';
+          StringAppend("%d%c" ,r->wvhdl[l][i+j],c);
+        }
+      }
+      else
+        StringAppend("(%d)",r->block1[l]-r->block0[l]+1);
+    }
+    if (l==nblocks) return omStrDup(StringAppendS(""));
+    StringAppendS(",");
+  }
+}
+
+char * rVarStr(ring r)
+{
+  int i;
+  int l=2;
+  char *s;
+
+  for (i=0; i<r->N; i++)
+  {
+    l+=strlen(r->names[i])+1;
+  }
+  s=(char *)omAlloc(l);
+  s[0]='\0';
+  for (i=0; i<r->N-1; i++)
+  {
+    strcat(s,r->names[i]);
+    strcat(s,",");
+  }
+  strcat(s,r->names[i]);
+  return s;
+}
+
+char * rCharStr(ring r)
+{
+  char *s;
+  int i;
+
+  if (r->parameter==NULL)
+  {
+    i=r->ch;
+    if(i==-1)
+      s=omStrDup("real");                    /* R */
+    else
+    {
+      s=(char *)omAlloc(6);
+      sprintf(s,"%d",i);                   /* Q, Z/p */
+    }
+    return s;
+  }
+  int l=0;
+  for(i=0; i<rPar(r);i++)
+  {
+    l+=(strlen(r->parameter[i])+1);
+  }
+  s=(char *)omAlloc(l+6);
+  s[0]='\0';
+  if (r->ch<0)       sprintf(s,"%d",-r->ch); /* Fp(a) */
+  else if (r->ch==1) sprintf(s,"0");         /* Q(a)  */
+  else
+  {
+    sprintf(s,"%d,%s",r->ch,r->parameter[0]); /* Fq  */
+    return s;
+  }
+  char tt[2];
+  tt[0]=',';
+  tt[1]='\0';
+  for(i=0; i<rPar(r);i++)
+  {
+    strcat(s,tt);
+    strcat(s,r->parameter[i]);
+  }
+  return s;
+}
+
+char * rParStr(ring r)
+{
+  if (r->parameter==NULL) return omStrDup("");
+
+  int i;
+  int l=2;
+
+  for (i=0; i<rPar(r); i++)
+  {
+    l+=strlen(r->parameter[i])+1;
+  }
+  char *s=(char *)omAlloc(l);
+  s[0]='\0';
+  for (i=0; i<rPar(r)-1; i++)
+  {
+    strcat(s,r->parameter[i]);
+    strcat(s,",");
+  }
+  strcat(s,r->parameter[i]);
+  return s;
+}
+
+char * rString(ring r)
+{
+  char *ch=rCharStr(r);
+  char *var=rVarStr(r);
+  char *ord=rOrdStr(r);
+  char *res=(char *)omAlloc(strlen(ch)+strlen(var)+strlen(ord)+9);
+  sprintf(res,"(%s),(%s),(%s)",ch,var,ord);
+  omFree((ADDRESS)ch);
+  omFree((ADDRESS)var);
+  omFree((ADDRESS)ord);
+  return res;
+}
+
+int  rIsExtension(ring r)
+{
+  return (r->parameter!=NULL); /* R, Q, Fp: FALSE */
+}
+
+int  rIsExtension()
+{
+  return rIsExtension( currRing );
+}
+
+int rChar(ring r)
+{
+  if (rField_is_numeric(r))
+    return 0;
+  if (!rIsExtension(r)) /* Q, Fp */
+    return r->ch;
+  if (rField_is_Zp_a(r))  /* Fp(a)  */
+    return -r->ch;
+  if (rField_is_Q_a(r))   /* Q(a)  */
+    return 0;
+  /*else*/               /* GF(p,n) */
+  {
+    if ((r->ch & 1)==0) return 2;
+    int i=3;
+    while ((r->ch % i)!=0) i+=2;
+    return i;
+  }
+}
+
+/*2
+ *returns -1 for not compatible, (sum is undefined)
+ *         0 for equal, (and sum)
+ *         1 for compatible (and sum)
+ */
+int rSum(ring r1, ring r2, ring &sum)
+{
+  if (r1==r2)
+  {
+    sum=r1;
+    r1->ref++;
+    return 0;
+  }
+  ring save=currRing;
+  ip_sring tmpR;
+  memset(&tmpR,0,sizeof(tmpR));
+  /* check coeff. field =====================================================*/
+  if (rInternalChar(r1)==rInternalChar(r2))
+  {
+    tmpR.ch=rInternalChar(r1);
+    if (rField_is_Q(r1)||rField_is_Zp(r1)||rField_is_GF(r1)) /*Q, Z/p, GF(p,n)*/
+    {
+      if (r1->parameter!=NULL)
+      {
+        if (strcmp(r1->parameter[0],r2->parameter[0])==0) /* 1 char */
+        {
+          tmpR.parameter=(char **)omAllocBin(char_ptr_bin);
+          tmpR.parameter[0]=omStrDup(r1->parameter[0]);
+          tmpR.P=1;
+        }
+        else
+        {
+          WerrorS("GF(p,n)+GF(p,n)");
+          return -1;
+        }
+      }
+    }
+    else if ((r1->ch==1)||(r1->ch<-1)) /* Q(a),Z/p(a) */
+    {
+      if (r1->minpoly!=NULL)
+      {
+        if (r2->minpoly!=NULL)
+        {
+          // HANNES: TODO: delete nSetChar
+          rChangeCurrRing(r1);
+          if ((strcmp(r1->parameter[0],r2->parameter[0])==0) /* 1 char */
+              && n_Equal(r1->minpoly,r2->minpoly, r1))
+          {
+            tmpR.parameter=(char **)omAllocBin(char_ptr_bin);
+            tmpR.parameter[0]=omStrDup(r1->parameter[0]);
+            tmpR.minpoly=n_Copy(r1->minpoly, r1);
+            tmpR.P=1;
+            // HANNES: TODO: delete nSetChar
+            rChangeCurrRing(save);
+          }
+          else
+          {
+            // HANNES: TODO: delete nSetChar
+            rChangeCurrRing(save);
+            WerrorS("different minpolys");
+            return -1;
+          }
+        }
+        else
+        {
+          if ((strcmp(r1->parameter[0],r2->parameter[0])==0) /* 1 char */
+              && (rPar(r2)==1))
+          {
+            tmpR.parameter=(char **)omAlloc0Bin(char_ptr_bin);
+            tmpR.parameter[0]=omStrDup(r1->parameter[0]);
+            tmpR.P=1;
+            tmpR.minpoly=n_Copy(r1->minpoly, r1);
+          }
+          else
+          {
+            WerrorS("different parameters and minpoly!=0");
+            return -1;
+          }
+        }
+      }
+      else /* r1->minpoly==NULL */
+      {
+        if (r2->minpoly!=NULL)
+        {
+          if ((strcmp(r1->parameter[0],r2->parameter[0])==0) /* 1 char */
+              && (rPar(r1)==1))
+          {
+            tmpR.parameter=(char **)omAllocBin(char_ptr_bin);
+            tmpR.parameter[0]=omStrDup(r1->parameter[0]);
+            tmpR.P=1;
+            tmpR.minpoly=n_Copy(r2->minpoly, r2);
+          }
+          else
+          {
+            WerrorS("different parameters and minpoly!=0");
+            return -1;
+          }
+        }
+        else
+        {
+          int len=rPar(r1)+rPar(r2);
+          tmpR.parameter=(char **)omAlloc(len*sizeof(char_ptr));
+          int i;
+          for (i=0;i<rPar(r1);i++)
+          {
+            tmpR.parameter[i]=omStrDup(r1->parameter[i]);
+          }
+          int j,l;
+          for(j=0;j<rPar(r2);j++)
+          {
+            for(l=0;l<i;l++)
+            {
+              if(strcmp(tmpR.parameter[l],r2->parameter[j])==0)
+                break;
+            }
+            if (l==i)
+            {
+              tmpR.parameter[i]=omStrDup(r2->parameter[j]);
+              i++;
+            }
+          }
+          if (i!=len)
+          {
+            omReallocSize(tmpR.parameter,len*sizeof(char_ptr),i*sizeof(char_ptr));
+          }
+        }
+      }
+    }
+  }
+  else /* r1->ch!=r2->ch */
+  {
+    if (r1->ch<-1) /* Z/p(a) */
+    {
+      if ((r2->ch==0) /* Q */
+          || (r2->ch==-r1->ch)) /* Z/p */
+      {
+        tmpR.ch=rInternalChar(r1);
+        tmpR.parameter=(char **)omAlloc(rPar(r1)*sizeof(char_ptr));
+        tmpR.P=rPar(r1);
+        memcpy(tmpR.parameter,r1->parameter,rPar(r1)*sizeof(char_ptr));
+        if (r1->minpoly!=NULL)
+        {
+          tmpR.minpoly=n_Copy(r1->minpoly, r1);
+        }
+      }
+      else  /* R, Q(a),Z/q,Z/p(a),GF(p,n) */
+      {
+        WerrorS("Z/p(a)+(R,Q(a),Z/q(a),GF(q,n))");
+        return -1;
+      }
+    }
+    else if (r1->ch==-1) /* R */
+    {
+      WerrorS("R+..");
+      return -1;
+    }
+    else if (r1->ch==0) /* Q */
+    {
+      if ((r2->ch<-1)||(r2->ch==1)) /* Z/p(a),Q(a) */
+      {
+        tmpR.ch=rInternalChar(r2);
+        tmpR.P=rPar(r2);
+        tmpR.parameter=(char **)omAlloc(rPar(r2)*sizeof(char_ptr));
+        memcpy(tmpR.parameter,r2->parameter,rPar(r2)*sizeof(char_ptr));
+        if (r2->minpoly!=NULL)
+        {
+          tmpR.minpoly=n_Copy(r2->minpoly, r2);
+        }
+      }
+      else if (r2->ch>1) /* Z/p,GF(p,n) */
+      {
+        tmpR.ch=r2->ch;
+        if (r2->parameter!=NULL)
+        {
+          tmpR.parameter=(char **)omAllocBin(char_ptr_bin);
+          tmpR.P=1;
+          tmpR.parameter[0]=omStrDup(r2->parameter[0]);
+        }
+      }
+      else
+      {
+        WerrorS("Q+R");
+        return -1; /* R */
+      }
+    }
+    else if (r1->ch==1) /* Q(a) */
+    {
+      if (r2->ch==0) /* Q */
+      {
+        tmpR.ch=rInternalChar(r1);
+        tmpR.P=rPar(r1);
+        tmpR.parameter=(char **)omAlloc0(rPar(r1)*sizeof(char_ptr));
+        int i;
+        for(i=0;i<rPar(r1);i++)
+        {
+          tmpR.parameter[i]=omStrDup(r1->parameter[i]);
+        }
+        if (r1->minpoly!=NULL)
+        {
+          tmpR.minpoly=n_Copy(r1->minpoly, r1);
+        }
+      }
+      else  /* R, Z/p,GF(p,n) */
+      {
+        WerrorS("Q(a)+(R,Z/p,GF(p,n))");
+        return -1;
+      }
+    }
+    else /* r1->ch >=2 , Z/p */
+    {
+      if (r2->ch==0) /* Q */
+      {
+        tmpR.ch=r1->ch;
+      }
+      else if (r2->ch==-r1->ch) /* Z/p(a) */
+      {
+        tmpR.ch=rInternalChar(r2);
+        tmpR.P=rPar(r2);
+        tmpR.parameter=(char **)omAlloc(rPar(r2)*sizeof(char_ptr));
+        int i;
+        for(i=0;i<rPar(r2);i++)
+        {
+          tmpR.parameter[i]=omStrDup(r2->parameter[i]);
+        }
+        if (r2->minpoly!=NULL)
+        {
+          tmpR.minpoly=n_Copy(r2->minpoly, r2);
+        }
+      }
+      else
+      {
+        WerrorS("Z/p+(GF(q,n),Z/q(a),R,Q(a))");
+        return -1; /* GF(p,n),Z/q(a),R,Q(a) */
+      }
+    }
+  }
+  /* variable names ========================================================*/
+  int i,j,k;
+  int l=r1->N+r2->N;
+  char **names=(char **)omAlloc0(l*sizeof(char_ptr));
+  k=0;
+
+  // collect all varnames from r1, except those which are parameters
+  // of r2, or those which are the empty string
+  for (i=0;i<r1->N;i++)
+  {
+    BOOLEAN b=TRUE;
+
+    if (*(r1->names[i]) == '\0')
+      b = FALSE;
+    else if ((r2->parameter!=NULL) && (strlen(r1->names[i])==1))
+    {
+      for(j=0;j<rPar(r2);j++)
+      {
+        if (strcmp(r1->names[i],r2->parameter[j])==0)
+        {
+          b=FALSE;
+          break;
+        }
+      }
+    }
+
+    if (b)
+    {
+      //Print("name : %d: %s\n",k,r1->names[i]);
+      names[k]=omStrDup(r1->names[i]);
+      k++;
+    }
+    //else
+    //  Print("no name (par1) %s\n",r1->names[i]);
+  }
+  // Add variables from r2, except those which are parameters of r1
+  // those which are empty strings, and those which equal a var of r1
+  for(i=0;i<r2->N;i++)
+  {
+    BOOLEAN b=TRUE;
+
+    if (*(r2->names[i]) == '\0')
+      b = FALSE;
+    else if ((r1->parameter!=NULL) && (strlen(r2->names[i])==1))
+    {
+      for(j=0;j<rPar(r1);j++)
+      {
+        if (strcmp(r2->names[i],r1->parameter[j])==0)
+        {
+          b=FALSE;
+          break;
+        }
+      }
+    }
+
+    if (b)
+    {
+      for(j=0;j<r1->N;j++)
+      {
+        if (strcmp(r1->names[j],r2->names[i])==0)
+        {
+          b=FALSE;
+          break;
+        }
+      }
+      if (b)
+      {
+        //Print("name : %d : %s\n",k,r2->names[i]);
+        names[k]=omStrDup(r2->names[i]);
+        k++;
+      }
+      //else
+      //  Print("no name (var): %s\n",r2->names[i]);
+    }
+    //else
+    //  Print("no name (par): %s\n",r2->names[i]);
+  }
+  // check whether we found any vars at all
+  if (k == 0)
+  {
+    names[k]=omStrDup("");
+    k=1;
+  }
+  tmpR.N=k;
+  tmpR.names=names;
+  /* ordering *======================================================== */
+  tmpR.OrdSgn=1;
+  if ((r1->order[0]==ringorder_unspec)
+      && (r2->order[0]==ringorder_unspec))
+  {
+    tmpR.order=(int*)omAlloc(3*sizeof(int));
+    tmpR.block0=(int*)omAlloc(3*sizeof(int));
+    tmpR.block1=(int*)omAlloc(3*sizeof(int));
+    tmpR.wvhdl=(int**)omAlloc0(3*sizeof(int_ptr));
+    tmpR.order[0]=ringorder_unspec;
+    tmpR.order[1]=ringorder_C;
+    tmpR.order[2]=0;
+    tmpR.block0[0]=1;
+    tmpR.block1[0]=tmpR.N;
+  }
+  else if (l==k) /* r3=r1+r2 */
+  {
+    int b;
+    ring rb;
+    if (r1->order[0]==ringorder_unspec)
+    {
+      /* extend order of r2 to r3 */
+      b=rBlocks(r2);
+      rb=r2;
+      tmpR.OrdSgn=r2->OrdSgn;
+    }
+    else if (r2->order[0]==ringorder_unspec)
+    {
+      /* extend order of r1 to r3 */
+      b=rBlocks(r1);
+      rb=r1;
+      tmpR.OrdSgn=r1->OrdSgn;
+    }
+    else
+    {
+      b=rBlocks(r1)+rBlocks(r2)-2; /* for only one order C, only one 0 */
+      rb=NULL;
+    }
+    tmpR.order=(int*)omAlloc0(b*sizeof(int));
+    tmpR.block0=(int*)omAlloc0(b*sizeof(int));
+    tmpR.block1=(int*)omAlloc0(b*sizeof(int));
+    tmpR.wvhdl=(int**)omAlloc0(b*sizeof(int_ptr));
+    /* weights not implemented yet ...*/
+    if (rb!=NULL)
+    {
+      for (i=0;i<b;i++)
+      {
+        tmpR.order[i]=rb->order[i];
+        tmpR.block0[i]=rb->block0[i];
+        tmpR.block1[i]=rb->block1[i];
+        if (rb->wvhdl[i]!=NULL)
+          WarnS("rSum: weights not implemented");
+      }
+      tmpR.block0[0]=1;
+    }
+    else /* ring sum for complete rings */
+    {
+      for (i=0;r1->order[i]!=0;i++)
+      {
+        tmpR.order[i]=r1->order[i];
+        tmpR.block0[i]=r1->block0[i];
+        tmpR.block1[i]=r1->block1[i];
+        if (r1->wvhdl[i]!=NULL)
+          tmpR.wvhdl[i] = (int*) omMemDup(r1->wvhdl[i]);
+      }
+      j=i;
+      i--;
+      if ((r1->order[i]==ringorder_c)
+          ||(r1->order[i]==ringorder_C))
+      {
+        j--;
+        tmpR.order[b-2]=r1->order[i];
+      }
+      for (i=0;r2->order[i]!=0;i++)
+      {
+        if ((r2->order[i]!=ringorder_c)
+            &&(r2->order[i]!=ringorder_C))
+        {
+          tmpR.order[j]=r2->order[i];
+          tmpR.block0[j]=r2->block0[i]+r1->N;
+          tmpR.block1[j]=r2->block1[i]+r1->N;
+          if (r2->wvhdl[i]!=NULL)
+          {
+            tmpR.wvhdl[j] = (int*) omMemDup(r2->wvhdl[i]);
+          }
+          j++;
+        }
+      }
+      if((r1->OrdSgn==-1)||(r2->OrdSgn==-1))
+        tmpR.OrdSgn=-1;
+    }
+  }
+  else if ((k==r1->N) && (k==r2->N)) /* r1 and r2 are "quite" the same ring */
+    /* copy r1, because we have the variables from r1 */
+  {
+    int b=rBlocks(r1);
+
+    tmpR.order=(int*)omAlloc0(b*sizeof(int));
+    tmpR.block0=(int*)omAlloc0(b*sizeof(int));
+    tmpR.block1=(int*)omAlloc0(b*sizeof(int));
+    tmpR.wvhdl=(int**)omAlloc0(b*sizeof(int_ptr));
+    /* weights not implemented yet ...*/
+    for (i=0;i<b;i++)
+    {
+      tmpR.order[i]=r1->order[i];
+      tmpR.block0[i]=r1->block0[i];
+      tmpR.block1[i]=r1->block1[i];
+      if (r1->wvhdl[i]!=NULL)
+      {
+        tmpR.wvhdl[i] = (int*) omMemDup(r1->wvhdl[i]);
+      }
+    }
+    tmpR.OrdSgn=r1->OrdSgn;
+  }
+  else
+  {
+    for(i=0;i<k;i++) omFree((ADDRESS)tmpR.names[i]);
+    omFreeSize((ADDRESS)names,tmpR.N*sizeof(char_ptr));
+    Werror("difficulties with variables: %d,%d -> %d",r1->N,r2->N,k);
+    return -1;
+  }
+  sum=(ring)omAllocBin(ip_sring_bin);
+  memcpy(sum,&tmpR,sizeof(ip_sring));
+  rComplete(sum);
+  return 1;
+}
+/*2
+ * create a copy of the ring r, which must be equivalent to currRing
+ * used for qring definition,..
+ * (i.e.: normal rings: same nCopy as currRing;
+ *        qring:        same nCopy, same idCopy as currRing)
+ * DOES NOT CALL rComplete
+ */
+static ring rCopy0(ring r, BOOLEAN copy_qideal = TRUE,
+                   BOOLEAN copy_ordering = TRUE)
+{
+  if (r == NULL) return NULL;
+  int i,j;
+  ring res=(ring)omAllocBin(ip_sring_bin);
+
+  memcpy4(res,r,sizeof(ip_sring));
+  res->VarOffset = NULL;
+  res->ref=0;
+  if (r->algring!=NULL)
+    r->algring->ref++;
+  if (r->parameter!=NULL)
+  {
+    res->minpoly=nCopy(r->minpoly);
+    int l=rPar(r);
+    res->parameter=(char **)omAlloc(l*sizeof(char_ptr));
+    int i;
+    for(i=0;i<rPar(r);i++)
+    {
+      res->parameter[i]=omStrDup(r->parameter[i]);
+    }
+  }
+  if (copy_ordering == TRUE)
+  {
+    i=rBlocks(r);
+    res->wvhdl   = (int **)omAlloc(i * sizeof(int_ptr));
+    res->order   = (int *) omAlloc(i * sizeof(int));
+    res->block0  = (int *) omAlloc(i * sizeof(int));
+    res->block1  = (int *) omAlloc(i * sizeof(int));
+    for (j=0; j<i; j++)
+    {
+      if (r->wvhdl[j]!=NULL)
+      {
+        res->wvhdl[j] = (int*) omMemDup(r->wvhdl[j]);
+      }
+      else
+        res->wvhdl[j]=NULL;
+    }
+    memcpy4(res->order,r->order,i * sizeof(int));
+    memcpy4(res->block0,r->block0,i * sizeof(int));
+    memcpy4(res->block1,r->block1,i * sizeof(int));
+  }
+  else
+  {
+    res->wvhdl = NULL;
+    res->order = NULL;
+    res->block0 = NULL;
+    res->block1 = NULL;
+  }
+
+  res->names   = (char **)omAlloc0(r->N * sizeof(char_ptr));
+  for (i=0; i<res->N; i++)
+  {
+    res->names[i] = omStrDup(r->names[i]);
+  }
+  res->idroot = NULL;
+  if (r->qideal!=NULL)
+  {
+    if (copy_qideal) res->qideal= idrCopyR_NoSort(r->qideal, r);
+    else res->qideal = NULL;
+  }
+#ifdef HAVE_PLURAL
+  if (rIsPluralRing(r))
+  {
+    res->nc->ref++;
+  }
+#endif
+  return res;
+}
+
+/*2
+ * create a copy of the ring r, which must be equivalent to currRing
+ * used for qring definition,..
+ * (i.e.: normal rings: same nCopy as currRing;
+ *        qring:        same nCopy, same idCopy as currRing)
+ */
+ring rCopy(ring r)
+{
+  if (r == NULL) return NULL;
+  ring res=rCopy0(r);
+  rComplete(res, 1);
+  return res;
+}
+
+// returns TRUE, if r1 equals r2 FALSE, otherwise Equality is
+// determined componentwise, if qr == 1, then qrideal equality is
+// tested, as well
+BOOLEAN rEqual(ring r1, ring r2, BOOLEAN qr)
+{
+  int i, j;
+
+  if (r1 == r2) return 1;
+
+  if (r1 == NULL || r2 == NULL) return 0;
+
+  if ((rInternalChar(r1) != rInternalChar(r2))
+  || (r1->float_len != r2->float_len)
+  || (r1->float_len2 != r2->float_len2)
+  || (r1->N != r2->N)
+  || (r1->OrdSgn != r2->OrdSgn)
+  || (rPar(r1) != rPar(r2)))
+    return 0;
+
+  for (i=0; i<r1->N; i++)
+  {
+    if (r1->names[i] != NULL && r2->names[i] != NULL)
+    {
+      if (strcmp(r1->names[i], r2->names[i])) return 0;
+    }
+    else if ((r1->names[i] != NULL) ^ (r2->names[i] != NULL))
+    {
+      return 0;
+    }
+  }
+
+  i=0;
+  while (r1->order[i] != 0)
+  {
+    if (r2->order[i] == 0) return 0;
+    if ((r1->order[i] != r2->order[i]) ||
+        (r1->block0[i] != r2->block0[i]) || (r2->block0[i] != r1->block0[i]))
+      return 0;
+    if (r1->wvhdl[i] != NULL)
+    {
+      if (r2->wvhdl[i] == NULL)
+        return 0;
+      for (j=0; j<r1->block1[i]-r1->block0[i]+1; j++)
+        if (r2->wvhdl[i][j] != r1->wvhdl[i][j])
+          return 0;
+    }
+    else if (r2->wvhdl[i] != NULL) return 0;
+    i++;
+  }
+
+  for (i=0; i<rPar(r1);i++)
+  {
+      if (strcmp(r1->parameter[i], r2->parameter[i])!=0)
+        return 0;
+  }
+
+  if (r1->minpoly != NULL)
+  {
+    if (r2->minpoly == NULL) return 0;
+    if (currRing == r1 || currRing == r2)
+    {
+      if (! nEqual(r1->minpoly, r2->minpoly)) return 0;
+    }
+  }
+  else if (r2->minpoly != NULL) return 0;
+
+  if (qr)
+  {
+    if (r1->qideal != NULL)
+    {
+      ideal id1 = r1->qideal, id2 = r2->qideal;
+      int i, n;
+      poly *m1, *m2;
+
+      if (id2 == NULL) return 0;
+      if ((n = IDELEMS(id1)) != IDELEMS(id2)) return 0;
+
+      if (currRing == r1 || currRing == r2)
+      {
+        m1 = id1->m;
+        m2 = id2->m;
+        for (i=0; i<n; i++)
+          if (! pEqualPolys(m1[i],m2[i])) return 0;
+      }
+    }
+    else if (r2->qideal != NULL) return 0;
+  }
+
+  return 1;
+}
+
+rOrderType_t rGetOrderType(ring r)
+{
+  // check for simple ordering
+  if (rHasSimpleOrder(r))
+  {
+    if ((r->order[1] == ringorder_c) || (r->order[1] == ringorder_C))
+    {
+      switch(r->order[0])
+      {
+          case ringorder_dp:
+          case ringorder_wp:
+          case ringorder_ds:
+          case ringorder_ws:
+          case ringorder_ls:
+          case ringorder_unspec:
+            if (r->order[1] == ringorder_C ||  r->order[0] == ringorder_unspec)
+              return rOrderType_ExpComp;
+            return rOrderType_Exp;
+
+          default:
+            assume(r->order[0] == ringorder_lp ||
+                   r->order[0] == ringorder_rp ||
+                   r->order[0] == ringorder_Dp ||
+                   r->order[0] == ringorder_Wp ||
+                   r->order[0] == ringorder_Ds ||
+                   r->order[0] == ringorder_Ws);
+
+            if (r->order[1] == ringorder_c) return rOrderType_ExpComp;
+            return rOrderType_Exp;
+      }
+    }
+    else
+    {
+      assume((r->order[0]==ringorder_c)||(r->order[0]==ringorder_C));
+      return rOrderType_CompExp;
+    }
+  }
+  else
+    return rOrderType_General;
+}
+
+BOOLEAN rHasSimpleOrder(ring r)
+{
+  if (r->order[0] == ringorder_unspec) return TRUE;
+  int blocks = rBlocks(r) - 1;
+  assume(blocks >= 1);
+  if (blocks == 1) return TRUE;
+  if (blocks > 2)  return FALSE;
+  if (r->order[0] != ringorder_c && r->order[0] != ringorder_C &&
+      r->order[1] != ringorder_c && r->order[1] != ringorder_C)
+    return FALSE;
+  if (r->order[1] == ringorder_M || r->order[0] == ringorder_M)
+    return FALSE;
+  return TRUE;
+}
+
+// returns TRUE, if simple lp or ls ordering
+BOOLEAN rHasSimpleLexOrder(ring r)
+{
+  return rHasSimpleOrder(r) &&
+    (r->order[0] == ringorder_ls ||
+     r->order[0] == ringorder_lp ||
+     r->order[1] == ringorder_ls ||
+     r->order[1] == ringorder_lp);
+}
+
+BOOLEAN rOrder_is_DegOrdering(rRingOrder_t order)
+{
+  switch(order)
+  {
+      case ringorder_dp:
+      case ringorder_Dp:
+      case ringorder_ds:
+      case ringorder_Ds:
+      case ringorder_Ws:
+      case ringorder_Wp:
+      case ringorder_ws:
+      case ringorder_wp:
+        return TRUE;
+
+      default:
+        return FALSE;
+  }
+}
+
+BOOLEAN rOrder_is_WeightedOrdering(rRingOrder_t order)
+{
+  switch(order)
+  {
+      case ringorder_Ws:
+      case ringorder_Wp:
+      case ringorder_ws:
+      case ringorder_wp:
+        return TRUE;
+
+      default:
+        return FALSE;
+  }
+}
+
+BOOLEAN rHasSimpleOrderAA(ring r)
+{
+  int blocks = rBlocks(r) - 1;
+  if (blocks > 3 || blocks < 2) return FALSE;
+  if (blocks == 3)
+  {
+    return ((r->order[0] == ringorder_aa && r->order[1] != ringorder_M &&
+             (r->order[2] == ringorder_c || r->order[2] == ringorder_C)) ||
+            ((r->order[0] == ringorder_c || r->order[0] == ringorder_C) &&
+             r->order[1] == ringorder_aa && r->order[2] != ringorder_M));
+  }
+  else
+  {
+    return (r->order[0] == ringorder_aa && r->order[1] != ringorder_M);
+  }
+}
+
+// return TRUE if p_SetComp requires p_Setm
+BOOLEAN rOrd_SetCompRequiresSetm(ring r)
+{
+  if (r->typ != NULL)
+  {
+    int pos;
+    for (pos=0;pos<r->OrdSize;pos++)
+    {
+      sro_ord* o=&(r->typ[pos]);
+      if (o->ord_typ == ro_syzcomp || o->ord_typ == ro_syz) return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+// return TRUE if p->exp[r->pOrdIndex] holds total degree of p */
+BOOLEAN rOrd_is_Totaldegree_Ordering(ring r)
+{
+  // Hmm.... what about Syz orderings?
+  return (r->N > 1 &&
+          ((rHasSimpleOrder(r) &&
+           (rOrder_is_DegOrdering((rRingOrder_t)r->order[0]) ||
+            rOrder_is_DegOrdering(( rRingOrder_t)r->order[1]))) ||
+           (rHasSimpleOrderAA(r) &&
+            (rOrder_is_DegOrdering((rRingOrder_t)r->order[1]) ||
+             rOrder_is_DegOrdering((rRingOrder_t)r->order[2])))));
+}
+
+// return TRUE if p->exp[r->pOrdIndex] holds a weighted degree of p */
+BOOLEAN rOrd_is_WeightedDegree_Ordering(ring r =currRing)
+{
+  // Hmm.... what about Syz orderings?
+  return (r->N > 1 &&
+          rHasSimpleOrder(r) &&
+          (rOrder_is_WeightedOrdering((rRingOrder_t)r->order[0]) ||
+           rOrder_is_WeightedOrdering(( rRingOrder_t)r->order[1])));
+}
+
+BOOLEAN rIsPolyVar(int v, ring r)
+{
+  int  i=0;
+  while(r->order[i]!=0)
+  {
+    if((r->block0[i]<=v)
+    && (r->block1[i]>=v))
+    {
+      switch(r->order[i])
+      {
+        case ringorder_a:
+          return (r->wvhdl[i][v-r->block0[i]]>0);
+        case ringorder_M:
+          return 2; /*don't know*/
+        case ringorder_lp:
+        case ringorder_rp:
+        case ringorder_dp:
+        case ringorder_Dp:
+        case ringorder_wp:
+        case ringorder_Wp:
+          return TRUE;
+        case ringorder_ls:
+        case ringorder_ds:
+        case ringorder_Ds:
+        case ringorder_ws:
+        case ringorder_Ws:
+          return FALSE;
+        default:
+          break;
+      }
+    }
+    i++;
+  }
+  return 3; /* could not find var v*/
+}
+
+#ifdef RDEBUG
+// This should eventually become a full-fledge ring check, like pTest
+BOOLEAN rDBTest(ring r, char* fn, int l)
+{
+  int i,j;
+
+  if (r == NULL)
+  {
+    dReportError("Null ring in %s:%d", fn, l);
+    return FALSE;
+  }
+
+
+  if (r->N == 0) return TRUE;
+
+//  omCheckAddrSize(r,sizeof(ip_sring));
+#if OM_CHECK > 0
+  i=rBlocks(r);
+  omCheckAddrSize(r->order,i*sizeof(int));
+  omCheckAddrSize(r->block0,i*sizeof(int));
+  omCheckAddrSize(r->block1,i*sizeof(int));
+  omCheckAddrSize(r->wvhdl,i*sizeof(int *));
+  for (j=0;j<i; j++)
+  {
+    if (r->wvhdl[j] != NULL) omCheckAddr(r->wvhdl[j]);
+  }
+#endif
+  if (r->VarOffset == NULL)
+  {
+    dReportError("Null ring VarOffset -- no rComplete (?) in n %s:%d", fn, l);
+    return FALSE;
+  }
+  omCheckAddrSize(r->VarOffset,(r->N+1)*sizeof(int));
+
+  if ((r->OrdSize==0)!=(r->typ==NULL))
+  {
+    dReportError("mismatch OrdSize and typ-pointer in %s:%d");
+    return FALSE;
+  }
+  omcheckAddrSize(r->typ,r->OrdSize*sizeof(*(r->typ)));
+  omCheckAddrSize(r->VarOffset,(r->N+1)*sizeof(*(r->VarOffset)));
+  // test assumptions:
+  for(i=0;i<=r->N;i++)
+  {
+    if(r->typ!=NULL)
+    {
+      for(j=0;j<r->OrdSize;j++)
+      {
+        if (r->typ[j].ord_typ==ro_cp)
+        {
+          if(((short)r->VarOffset[i]) == r->typ[j].data.cp.place)
+            dReportError("ordrec %d conflicts with var %d",j,i);
+        }
+        else
+          if ((r->typ[j].ord_typ!=ro_syzcomp)
+          && (r->VarOffset[i] == r->typ[j].data.dp.place))
+            dReportError("ordrec %d conflicts with var %d",j,i);
+      }
+    }
+    int tmp;
+      tmp=r->VarOffset[i] & 0xffffff;
+      #if SIZEOF_LONG == 8
+        if ((r->VarOffset[i] >> 24) >63)
+      #else
+        if ((r->VarOffset[i] >> 24) >31)
+      #endif
+          dReportError("bit_start out of range:%d",r->VarOffset[i] >> 24);
+      if (i > 0 && ((tmp<0) ||(tmp>r->ExpL_Size-1)))
+      {
+        dReportError("varoffset out of range for var %d: %d",i,tmp);
+      }
+  }
+  if(r->typ!=NULL)
+  {
+    for(j=0;j<r->OrdSize;j++)
+    {
+      if ((r->typ[j].ord_typ==ro_dp)
+      || (r->typ[j].ord_typ==ro_wp)
+      || (r->typ[j].ord_typ==ro_wp_neg))
+      {
+        if (r->typ[j].data.dp.start > r->typ[j].data.dp.end)
+          dReportError("in ordrec %d: start(%d) > end(%d)",j,
+            r->typ[j].data.dp.start, r->typ[j].data.dp.end);
+        if ((r->typ[j].data.dp.start < 1)
+        || (r->typ[j].data.dp.end > r->N))
+          dReportError("in ordrec %d: start(%d)<1 or end(%d)>vars(%d)",j,
+            r->typ[j].data.dp.start, r->typ[j].data.dp.end,r->N);
+      }
+    }
+  }
+  //assume(r->cf!=NULL);
+
+  return TRUE;
+}
+#endif
+
+static void rO_Align(int &place, int &bitplace)
+{
+  // increment place to the next aligned one
+  // (count as Exponent_t,align as longs)
+  if (bitplace!=BITS_PER_LONG)
+  {
+    place++;
+    bitplace=BITS_PER_LONG;
+  }
+}
+
+static void rO_TDegree(int &place, int &bitplace, int start, int end,
+    long *o, sro_ord &ord_struct)
+{
+  // degree (aligned) of variables v_start..v_end, ordsgn 1
+  rO_Align(place,bitplace);
+  ord_struct.ord_typ=ro_dp;
+  ord_struct.data.dp.start=start;
+  ord_struct.data.dp.end=end;
+  ord_struct.data.dp.place=place;
+  o[place]=1;
+  place++;
+  rO_Align(place,bitplace);
+}
+
+static void rO_TDegree_neg(int &place, int &bitplace, int start, int end,
+    long *o, sro_ord &ord_struct)
+{
+  // degree (aligned) of variables v_start..v_end, ordsgn -1
+  rO_Align(place,bitplace);
+  ord_struct.ord_typ=ro_dp;
+  ord_struct.data.dp.start=start;
+  ord_struct.data.dp.end=end;
+  ord_struct.data.dp.place=place;
+  o[place]=-1;
+  place++;
+  rO_Align(place,bitplace);
+}
+
+static void rO_WDegree(int &place, int &bitplace, int start, int end,
+    long *o, sro_ord &ord_struct, int *weights)
+{
+  // weighted degree (aligned) of variables v_start..v_end, ordsgn 1
+  rO_Align(place,bitplace);
+  ord_struct.ord_typ=ro_wp;
+  ord_struct.data.wp.start=start;
+  ord_struct.data.wp.end=end;
+  ord_struct.data.wp.place=place;
+  ord_struct.data.wp.weights=weights;
+  o[place]=1;
+  place++;
+  rO_Align(place,bitplace);
+  int i;
+  for(i=start;i<=end;i++)
+  {
+    if(weights[i-start]<0)
+    {
+      ord_struct.ord_typ=ro_wp_neg;
+      break;
+    }
+  }
+}
+
+static void rO_WDegree_neg(int &place, int &bitplace, int start, int end,
+    long *o, sro_ord &ord_struct, int *weights)
+{
+  // weighted degree (aligned) of variables v_start..v_end, ordsgn -1
+  rO_Align(place,bitplace);
+  ord_struct.ord_typ=ro_wp;
+  ord_struct.data.wp.start=start;
+  ord_struct.data.wp.end=end;
+  ord_struct.data.wp.place=place;
+  ord_struct.data.wp.weights=weights;
+  o[place]=-1;
+  place++;
+  rO_Align(place,bitplace);
+  int i;
+  for(i=start;i<=end;i++)
+  {
+    if(weights[i-start]<0)
+    {
+      ord_struct.ord_typ=ro_wp_neg;
+      break;
+    }
+  }
+}
+
+static void rO_LexVars(int &place, int &bitplace, int start, int end,
+  int &prev_ord, long *o,int *v, int bits, int opt_var)
+{
+  // a block of variables v_start..v_end with lex order, ordsgn 1
+  int k;
+  int incr=1;
+  if(prev_ord==-1) rO_Align(place,bitplace);
+
+  if (start>end)
+  {
+    incr=-1;
+  }
+  for(k=start;;k+=incr)
+  {
+    bitplace-=bits;
+    if (bitplace < 0) { bitplace=BITS_PER_LONG-bits; place++; }
+    o[place]=1;
+    v[k]= place | (bitplace << 24);
+    if (k==end) break;
+  }
+  prev_ord=1;
+  if (opt_var!= -1)
+  {
+    assume((opt_var == end+1) ||(opt_var == end-1));
+    if((opt_var != end+1) &&(opt_var != end-1)) WarnS("hier-2");
+    int save_bitplace=bitplace;
+    bitplace-=bits;
+    if (bitplace < 0)
+    {
+      bitplace=save_bitplace;
+      return;
+    }
+    // there is enough space for the optional var
+    v[opt_var]=place | (bitplace << 24);
+  }
+}
+
+static void rO_LexVars_neg(int &place, int &bitplace, int start, int end,
+  int &prev_ord, long *o,int *v, int bits, int opt_var)
+{
+  // a block of variables v_start..v_end with lex order, ordsgn -1
+  int k;
+  int incr=1;
+  if(prev_ord==1) rO_Align(place,bitplace);
+
+  if (start>end)
+  {
+    incr=-1;
+  }
+  for(k=start;;k+=incr)
+  {
+    bitplace-=bits;
+    if (bitplace < 0) { bitplace=BITS_PER_LONG-bits; place++; }
+    o[place]=-1;
+    v[k]=place | (bitplace << 24);
+    if (k==end) break;
+  }
+  prev_ord=-1;
+//  #if 0
+  if (opt_var!= -1)
+  {
+    assume((opt_var == end+1) ||(opt_var == end-1));
+    if((opt_var != end+1) &&(opt_var != end-1)) WarnS("hier-1");
+    int save_bitplace=bitplace;
+    bitplace-=bits;
+    if (bitplace < 0)
+    {
+      bitplace=save_bitplace;
+      return;
+    }
+    // there is enough space for the optional var
+    v[opt_var]=place | (bitplace << 24);
+  }
+//  #endif
+}
+
+static void rO_Syzcomp(int &place, int &bitplace, int &prev_ord,
+    long *o, sro_ord &ord_struct)
+{
+  // ordering is derived from component number
+  rO_Align(place,bitplace);
+  ord_struct.ord_typ=ro_syzcomp;
+  ord_struct.data.syzcomp.place=place;
+  ord_struct.data.syzcomp.Components=NULL;
+  ord_struct.data.syzcomp.ShiftedComponents=NULL;
+  o[place]=1;
+  prev_ord=1;
+  place++;
+  rO_Align(place,bitplace);
+}
+
+static void rO_Syz(int &place, int &bitplace, int &prev_ord,
+    long *o, sro_ord &ord_struct)
+{
+  // ordering is derived from component number
+  // let's reserve one Exponent_t for it
+  if ((prev_ord== 1) || (bitplace!=BITS_PER_LONG))
+    rO_Align(place,bitplace);
+  ord_struct.ord_typ=ro_syz;
+  ord_struct.data.syz.place=place;
+  ord_struct.data.syz.limit=0;
+  ord_struct.data.syz.syz_index = NULL;
+  ord_struct.data.syz.curr_index = 1;
+  o[place]= -1;
+  prev_ord=-1;
+  place++;
+}
+
+static unsigned long rGetExpSize(unsigned long bitmask, int & bits)
+{
+  if (bitmask == 0)
+  {
+    bits=16; bitmask=0xffff;
+  }
+  else if (bitmask <= 1)
+  {
+    bits=1; bitmask = 1;
+  }
+  else if (bitmask <= 3)
+  {
+    bits=2; bitmask = 3;
+  }
+  else if (bitmask <= 7)
+  {
+    bits=3; bitmask=7;
+  }
+  else if (bitmask <= 0xf)
+  {
+    bits=4; bitmask=0xf;
+  }
+  else if (bitmask <= 0x1f)
+  {
+    bits=5; bitmask=0x1f;
+  }
+  else if (bitmask <= 0x3f)
+  {
+    bits=6; bitmask=0x3f;
+  }
+#if SIZEOF_LONG == 8
+  else if (bitmask <= 0x7f)
+  {
+    bits=7; bitmask=0x7f; /* 64 bit longs only */
+  }
+#endif
+  else if (bitmask <= 0xff)
+  {
+    bits=8; bitmask=0xff;
+  }
+#if SIZEOF_LONG == 8
+  else if (bitmask <= 0x1ff)
+  {
+    bits=9; bitmask=0x1ff; /* 64 bit longs only */
+  }
+#endif
+  else if (bitmask <= 0x3ff)
+  {
+    bits=10; bitmask=0x3ff;
+  }
+#if SIZEOF_LONG == 8
+  else if (bitmask <= 0xfff)
+  {
+    bits=12; bitmask=0xfff; /* 64 bit longs only */
+  }
+#endif
+  else if (bitmask <= 0xffff)
+  {
+    bits=16; bitmask=0xffff;
+  }
+#if SIZEOF_LONG == 8
+  else if (bitmask <= 0xfffff)
+  {
+    bits=20; bitmask=0xfffff; /* 64 bit longs only */
+  }
+  else if (bitmask <= 0xffffffff)
+  {
+    bits=32; bitmask=0xffffffff;
+  }
+  else
+  {
+    bits=64; bitmask=0xffffffffffffffff;
+  }
+#else
+  else
+  {
+    bits=32; bitmask=0xffffffff;
+  }
+#endif
+  return bitmask;
+}
+
+/*2
+* optimize rGetExpSize for a block of N variables, exp <=bitmask
+*/
+static unsigned long rGetExpSize(unsigned long bitmask, int & bits, int N)
+{
+  bitmask =rGetExpSize(bitmask, bits);
+  int vars_per_long=BIT_SIZEOF_LONG/bits;
+  int bits1;
+  loop
+  {
+    if (bits == BIT_SIZEOF_LONG)
+    {
+      bits =  BIT_SIZEOF_LONG - 1;
+      return LONG_MAX;
+    }
+    unsigned long bitmask1 =rGetExpSize(bitmask+1, bits1);
+    int vars_per_long1=BIT_SIZEOF_LONG/bits1;
+    if ((((N+vars_per_long-1)/vars_per_long) ==
+         ((N+vars_per_long1-1)/vars_per_long1)))
+    {
+      vars_per_long=vars_per_long1;
+      bits=bits1;
+      bitmask=bitmask1;
+    }
+    else
+    {
+      return bitmask; /* and bits */
+    }
+  }
+}
+
+/*2
+ * create a copy of the ring r, which must be equivalent to currRing
+ * used for std computations
+ * may share data structures with currRing
+ * DOES CALL rComplete
+ */
+ring rModifyRing(ring r, BOOLEAN omit_degree,
+                         BOOLEAN omit_comp,
+                         unsigned long exp_limit)
+{
+  assume (r != NULL );
+  assume (exp_limit > 1);
+  BOOLEAN need_other_ring;
+  BOOLEAN omitted_degree = FALSE;
+  int bits;
+
+  exp_limit=rGetExpSize(exp_limit, bits, r->N);
+  need_other_ring = (exp_limit != r->bitmask);
+
+  int nblocks=rBlocks(r);
+  int *order=(int*)omAlloc0((nblocks+1)*sizeof(int));
+  int *block0=(int*)omAlloc0((nblocks+1)*sizeof(int));
+  int *block1=(int*)omAlloc0((nblocks+1)*sizeof(int));
+  int **wvhdl=(int**)omAlloc0((nblocks+1)*sizeof(int_ptr));
+
+  int i=0;
+  int j=0; /*  i index in r, j index in res */
+  loop
+  {
+    BOOLEAN copy_block_index=TRUE;
+    int r_ord=r->order[i];
+    if (r->block0[i]==r->block1[i])
+    {
+      switch(r_ord)
+      {
+        case ringorder_wp:
+        case ringorder_dp:
+        case ringorder_Wp:
+        case ringorder_Dp:
+          r_ord=ringorder_lp;
+          break;
+        case ringorder_Ws:
+        case ringorder_Ds:
+        case ringorder_ws:
+        case ringorder_ds:
+          r_ord=ringorder_ls;
+          break;
+        default:
+          break;
+      }
+    }
+    switch(r_ord)
+    {
+      case ringorder_C:
+      case ringorder_c:
+        if (!omit_comp)
+        {
+          order[j]=r_ord; /*r->order[i]*/;
+        }
+        else
+        {
+          j--;
+          need_other_ring=TRUE;
+          omit_comp=FALSE;
+          copy_block_index=FALSE;
+        }
+        break;
+      case ringorder_wp:
+      case ringorder_dp:
+      case ringorder_ws:
+      case ringorder_ds:
+        if(!omit_degree)
+        {
+          order[j]=r_ord; /*r->order[i]*/;
+        }
+        else
+        {
+          order[j]=ringorder_rp;
+          need_other_ring=TRUE;
+          omit_degree=FALSE;
+          omitted_degree = TRUE;
+        }
+        break;
+      case ringorder_Wp:
+      case ringorder_Dp:
+      case ringorder_Ws:
+      case ringorder_Ds:
+        if(!omit_degree)
+        {
+          order[j]=r_ord; /*r->order[i];*/
+        }
+        else
+        {
+          order[j]=ringorder_lp;
+          need_other_ring=TRUE;
+          omit_degree=FALSE;
+          omitted_degree = TRUE;
+        }
+        break;
+      default:
+        order[j]=r_ord; /*r->order[i];*/
+        break;
+    }
+    if (copy_block_index)
+    {
+      block0[j]=r->block0[i];
+      block1[j]=r->block1[i];
+      wvhdl[j]=r->wvhdl[i];
+    }
+    i++;j++;
+    // order[j]=ringorder_no; //  done by omAlloc0
+    if (i==nblocks) break;
+  }
+  if(!need_other_ring)
+  {
+    omFreeSize(order,(nblocks+1)*sizeof(int));
+    omFreeSize(block0,(nblocks+1)*sizeof(int));
+    omFreeSize(block1,(nblocks+1)*sizeof(int));
+    omFreeSize(wvhdl,(nblocks+1)*sizeof(int_ptr));
+    return r;
+  }
+  ring res=(ring)omAlloc0Bin(ip_sring_bin);
+  *res = *r;
+  // res->qideal, res->idroot ???
+  res->wvhdl=wvhdl;
+  res->order=order;
+  res->block0=block0;
+  res->block1=block1;
+  res->bitmask=exp_limit;
+  int tmpref=r->cf->ref;
+  rComplete(res, 1);
+  r->cf->ref=tmpref;
+
+  // adjust res->pFDeg: if it was changed globally, then
+  // it must also be changed for new ring
+  if (r->pFDegOrig != res->pFDegOrig &&
+           rOrd_is_WeightedDegree_Ordering(r))
+  {
+    // still might need adjustment for weighted orderings
+    // and omit_degree
+    res->firstwv = r->firstwv;
+    res->firstBlockEnds = r->firstBlockEnds;
+    res->pFDeg = res->pFDegOrig = pWFirstTotalDegree;
+  }
+  if (omitted_degree)
+    res->pLDeg = res->pLDegOrig = r->pLDegOrig;
+
+  rOptimizeLDeg(res);
+
+  // set syzcomp
+  if (res->typ != NULL && res->typ[0].ord_typ == ro_syz)
+  {
+    res->typ[0] = r->typ[0];
+    if (r->typ[0].data.syz.limit > 0)
+    {
+      res->typ[0].data.syz.syz_index
+        = (int*) omAlloc((r->typ[0].data.syz.limit +1)*sizeof(int));
+      memcpy(res->typ[0].data.syz.syz_index, r->typ[0].data.syz.syz_index,
+             (r->typ[0].data.syz.limit +1)*sizeof(int));
+    }
+  }
+  return res;
+}
+
+// construct Wp,C ring
+ring rModifyRing_Wp(ring r, int* weights)
+{
+  ring res=(ring)omAlloc0Bin(ip_sring_bin);
+  *res = *r;
+  /*weights: entries for 3 blocks: NULL*/
+  res->wvhdl = (int **)omAlloc0(3 * sizeof(int_ptr));
+  /*order: dp,C,0*/
+  res->order = (int *) omAlloc(3 * sizeof(int *));
+  res->block0 = (int *)omAlloc0(3 * sizeof(int *));
+  res->block1 = (int *)omAlloc0(3 * sizeof(int *));
+  /* ringorder dp for the first block: var 1..3 */
+  res->order[0]  = ringorder_Wp;
+  res->block0[0] = 1;
+  res->block1[0] = r->N;
+  res->wvhdl[0] = weights;
+  /* ringorder C for the second block: no vars */
+  res->order[1]  = ringorder_C;
+  /* the last block: everything is 0 */
+  res->order[2]  = 0;
+  /*polynomial ring*/
+  res->OrdSgn    = 1;
+
+  int tmpref=r->cf->ref;
+  rComplete(res, 1);
+  r->cf->ref=tmpref;
+  return res;
+}
+
+// construct lp ring with r->N variables, r->names vars....
+ring rModifyRing_Simple(ring r, BOOLEAN ommit_degree, BOOLEAN ommit_comp, unsigned long exp_limit, BOOLEAN &simple)
+{
+  simple=TRUE;
+  if (!rHasSimpleOrder(r))
+  {
+    simple=FALSE; // sorting needed
+    assume (r != NULL );
+    assume (exp_limit > 1);
+    BOOLEAN omitted_degree = FALSE;
+    int bits;
+
+    exp_limit=rGetExpSize(exp_limit, bits, r->N);
+
+    int nblocks=1+(ommit_comp!=0);
+    int *order=(int*)omAlloc0((nblocks+1)*sizeof(int));
+    int *block0=(int*)omAlloc0((nblocks+1)*sizeof(int));
+    int *block1=(int*)omAlloc0((nblocks+1)*sizeof(int));
+    int **wvhdl=(int**)omAlloc0((nblocks+1)*sizeof(int_ptr));
+
+    order[0]=ringorder_lp;
+    block0[0]=1;
+    block1[0]=r->N;
+    if (!ommit_comp)
+    {
+      order[1]=ringorder_C;
+    }
+    ring res=(ring)omAlloc0Bin(ip_sring_bin);
+    *res = *r;
+    // res->qideal, res->idroot ???
+    res->wvhdl=wvhdl;
+    res->order=order;
+    res->block0=block0;
+    res->block1=block1;
+    res->bitmask=exp_limit;
+    int tmpref=r->cf->ref;
+    rComplete(res, 1);
+    r->cf->ref=tmpref;
+
+    rOptimizeLDeg(res);
+
+    return res;
+  }
+  return rModifyRing(r, ommit_degree, ommit_comp, exp_limit);
+}
+
+void rKillModifiedRing_Simple(ring r)
+{
+  rKillModifiedRing(r);
+}
+
+
+void rKillModifiedRing(ring r)
+{
+  rUnComplete(r);
+  omFree(r->order);
+  omFree(r->block0);
+  omFree(r->block1);
+  omFree(r->wvhdl);
+  omFreeBin(r,ip_sring_bin);
+}
+
+void rKillModified_Wp_Ring(ring r)
+{
+  rUnComplete(r);
+  omFree(r->order);
+  omFree(r->block0);
+  omFree(r->block1);
+  omFree(r->wvhdl[0]);
+  omFree(r->wvhdl);
+  omFreeBin(r,ip_sring_bin);
+}
+
+static void rSetOutParams(ring r)
+{
+  r->VectorOut = (r->order[0] == ringorder_c);
+  r->ShortOut = TRUE;
+#ifdef HAVE_TCL
+  if (tcllmode)
+  {
+    r->ShortOut = FALSE;
+  }
+  else
+#endif
+  {
+    int i;
+    if ((r->parameter!=NULL) && (r->ch<2))
+    {
+      for (i=0;i<rPar(r);i++)
+      {
+        if(strlen(r->parameter[i])>1)
+        {
+          r->ShortOut=FALSE;
+          break;
+        }
+      }
+    }
+    if (r->ShortOut)
+    {
+      // Hmm... sometimes (e.g., from maGetPreimage) new variables
+      // are intorduced, but their names are never set
+      // hence, we do the following awkward trick
+      int N = omSizeWOfAddr(r->names);
+      if (r->N < N) N = r->N;
+
+      for (i=(N-1);i>=0;i--)
+      {
+        if(r->names[i] != NULL && strlen(r->names[i])>1)
+        {
+          r->ShortOut=FALSE;
+          break;
+        }
+      }
+    }
+  }
+  r->CanShortOut = r->ShortOut;
+}
+
+/*2
+* sets pMixedOrder and pComponentOrder for orderings with more than one block
+* block of variables (ip is the block number, o_r the number of the ordering)
+* o is the position of the orderingering in r
+*/
+static void rHighSet(ring r, int o_r, int o)
+{
+  switch(o_r)
+  {
+    case ringorder_lp:
+    case ringorder_dp:
+    case ringorder_Dp:
+    case ringorder_wp:
+    case ringorder_Wp:
+    case ringorder_rp:
+    case ringorder_a:
+    case ringorder_aa:
+      if (r->OrdSgn==-1) r->MixedOrder=TRUE;
+      break;
+    case ringorder_ls:
+    case ringorder_ds:
+    case ringorder_Ds:
+    case ringorder_s:
+      break;
+    case ringorder_ws:
+    case ringorder_Ws:
+      if (r->wvhdl[o]!=NULL)
+      {
+        int i;
+        for(i=r->block1[o]-r->block0[o];i>=0;i--)
+          if (r->wvhdl[o][i]<0) { r->MixedOrder=TRUE; break; }
+      }
+      break;
+    case ringorder_c:
+      r->ComponentOrder=1;
+      break;
+    case ringorder_C:
+    case ringorder_S:
+      r->ComponentOrder=-1;
+      break;
+    case ringorder_M:
+      r->MixedOrder=TRUE;
+      break;
+    default:
+      dReportError("wrong internal ordering:%d at %s, l:%d\n",o_r,__FILE__,__LINE__);
+  }
+}
+
+static void rSetFirstWv(ring r, int i, int* order, int* block1, int** wvhdl)
+{
+  // cheat for ringorder_aa
+  if (order[i] == ringorder_aa)
+    i++;
+  if(block1[i]!=r->N) r->LexOrder=TRUE;
+  r->firstBlockEnds=block1[i];
+  r->firstwv = wvhdl[i];
+  if ((order[i]== ringorder_ws) || (order[i]==ringorder_Ws))
+  {
+    int j;
+    for(j=block1[i]-r->block0[i];j>=0;j--)
+      if (r->firstwv[j]<0) { r->MixedOrder=TRUE; break; }
+  }
+}
+
+static void rOptimizeLDeg(ring r)
+{
+  if (r->pFDeg == pDeg)
+  {
+    if (r->pLDeg == pLDeg1)
+      r->pLDeg = pLDeg1_Deg;
+    if (r->pLDeg == pLDeg1c)
+      r->pLDeg = pLDeg1c_Deg;
+  }
+  else if (r->pFDeg == pTotaldegree)
+  {
+    if (r->pLDeg == pLDeg1)
+      r->pLDeg = pLDeg1_Totaldegree;
+    if (r->pLDeg == pLDeg1c)
+      r->pLDeg = pLDeg1c_Totaldegree;
+  }
+  else if (r->pFDeg == pWFirstTotalDegree)
+  {
+    if (r->pLDeg == pLDeg1)
+      r->pLDeg = pLDeg1_WFirstTotalDegree;
+    if (r->pLDeg == pLDeg1c)
+      r->pLDeg = pLDeg1c_WFirstTotalDegree;
+  }
+}
+
+// set pFDeg, pLDeg, MixOrder, ComponentOrder, etc
+static void rSetDegStuff(ring r)
+{
+  int* order = r->order;
+  int* block0 = r->block0;
+  int* block1 = r->block1;
+  int** wvhdl = r->wvhdl;
+
+  if (order[0]==ringorder_S ||order[0]==ringorder_s)
+  {
+    order++;
+    block0++;
+    block1++;
+    wvhdl++;
+  }
+  r->LexOrder = FALSE;
+  r->MixedOrder = FALSE;
+  r->ComponentOrder = 1;
+  r->pFDeg = pTotaldegree;
+  r->pLDeg = (r->OrdSgn == 1 ? pLDegb : pLDeg0);
+
+  /*======== ordering type is (_,c) =========================*/
+  if ((order[0]==ringorder_unspec) || (order[1] == 0)
+      ||(
+    ((order[1]==ringorder_c)||(order[1]==ringorder_C)
+     ||(order[1]==ringorder_S)
+     ||(order[1]==ringorder_s))
+    && (order[0]!=ringorder_M)
+    && (order[2]==0))
+    )
+  {
+    if ((order[0]!=ringorder_unspec)
+    && ((order[1]==ringorder_C)||(order[1]==ringorder_S)||
+        (order[1]==ringorder_s)))
+      r->ComponentOrder=-1;
+    if (r->OrdSgn == -1) r->pLDeg = pLDeg0c;
+    if ((order[0] == ringorder_lp) || (order[0] == ringorder_ls) || order[0] == ringorder_rp)
+    {
+      r->LexOrder=TRUE;
+      r->pLDeg = pLDeg1c;
+    }
+    if (order[0] == ringorder_wp || order[0] == ringorder_Wp ||
+        order[0] == ringorder_ws || order[0] == ringorder_Ws)
+      r->pFDeg = pWFirstTotalDegree;
+    r->firstBlockEnds=block1[0];
+    r->firstwv = wvhdl[0];
+  }
+  /*======== ordering type is (c,_) =========================*/
+  else if (((order[0]==ringorder_c)
+            ||(order[0]==ringorder_C)
+            ||(order[0]==ringorder_S)
+            ||(order[0]==ringorder_s))
+  && (order[1]!=ringorder_M)
+  &&  (order[2]==0))
+  {
+    if ((order[0]==ringorder_C)||(order[0]==ringorder_S)||
+        order[0]==ringorder_s)
+      r->ComponentOrder=-1;
+    if ((order[1] == ringorder_lp) || (order[1] == ringorder_ls) || order[1] == ringorder_rp)
+    {
+      r->LexOrder=TRUE;
+      r->pLDeg = pLDeg1c;
+    }
+    r->firstBlockEnds=block1[1];
+    r->firstwv = wvhdl[1];
+    if (order[1] == ringorder_wp || order[1] == ringorder_Wp ||
+        order[1] == ringorder_ws || order[1] == ringorder_Ws)
+      r->pFDeg = pWFirstTotalDegree;
+  }
+  /*------- more than one block ----------------------*/
+  else
+  {
+    if ((r->VectorOut)||(order[0]==ringorder_C)||(order[0]==ringorder_S)||(order[0]==ringorder_s))
+    {
+      rSetFirstWv(r, 1, order, block1, wvhdl);
+    }
+    else
+      rSetFirstWv(r, 0, order, block1, wvhdl);
+
+    /*the number of orderings:*/
+    int i = 0;
+    while (order[++i] != 0);
+    do
+    {
+      i--;
+      rHighSet(r, order[i],i);
+    }
+    while (i != 0);
+
+    if ((order[0]!=ringorder_c)
+        && (order[0]!=ringorder_C)
+        && (order[0]!=ringorder_S)
+        && (order[0]!=ringorder_s))
+    {
+      r->pLDeg = pLDeg1c;
+    }
+    else
+    {
+      r->pLDeg = pLDeg1;
+    }
+    r->pFDeg = pWTotaldegree; // may be improved: pTotaldegree for lp/dp/ls/.. blocks
+  }
+  if (rOrd_is_Totaldegree_Ordering(r) || rOrd_is_WeightedDegree_Ordering(r))
+    r->pFDeg = pDeg;
+
+  r->pFDegOrig = r->pFDeg;
+  r->pLDegOrig = r->pLDeg;
+  rOptimizeLDeg(r);
+}
+
+/*2
+* set NegWeightL_Size, NegWeightL_Offset
+*/
+static void rSetNegWeight(ring r)
+{
+  int i,l;
+  if (r->typ!=NULL)
+  {
+    l=0;
+    for(i=0;i<r->OrdSize;i++)
+    {
+      if(r->typ[i].ord_typ==ro_wp_neg) l++;
+    }
+    if (l>0)
+    {
+      r->NegWeightL_Size=l;
+      r->NegWeightL_Offset=(int *) omAlloc(l*sizeof(int));
+      l=0;
+      for(i=0;i<r->OrdSize;i++)
+      {
+        if(r->typ[i].ord_typ==ro_wp_neg)
+        {
+          r->NegWeightL_Offset[l]=r->typ[i].data.wp.place;
+          l++;
+        }
+      }
+      return;
+    }
+  }
+  r->NegWeightL_Size = 0;
+  r->NegWeightL_Offset = NULL;
+}
+
+static void rSetOption(ring r)
+{
+  // set redthrough
+  if (!TEST_OPT_OLDSTD && r->OrdSgn == 1 && ! r->LexOrder)
+    r->options |= Sy_bit(OPT_REDTHROUGH);
+  else
+    r->options &= ~Sy_bit(OPT_REDTHROUGH);
+
+  // set intStrategy
+  if (rField_is_Extension(r) || rField_is_Q(r))
+    r->options |= Sy_bit(OPT_INTSTRATEGY);
+  else
+    r->options &= ~Sy_bit(OPT_INTSTRATEGY);
+
+  // set redTail
+  if (r->LexOrder || r->OrdSgn == -1 || rField_is_Extension(r))
+    r->options &= ~Sy_bit(OPT_REDTAIL);
+  else
+    r->options |= Sy_bit(OPT_REDTAIL);
+}
+
+BOOLEAN rComplete(ring r, int force)
+{
+  if (r->VarOffset!=NULL && force == 0) return FALSE;
+  nInitChar(r);
+  rSetOutParams(r);
+  int n=rBlocks(r)-1;
+  int i;
+  int bits;
+  r->bitmask=rGetExpSize(r->bitmask,bits,r->N);
+  r->BitsPerExp = bits;
+  r->ExpPerLong = BIT_SIZEOF_LONG / bits;
+  r->divmask=rGetDivMask(bits);
+
+  // will be used for ordsgn:
+  long *tmp_ordsgn=(long *)omAlloc0(2*(n+r->N)*sizeof(long));
+  // will be used for VarOffset:
+  int *v=(int *)omAlloc((r->N+1)*sizeof(int));
+  for(i=r->N; i>=0 ; i--)
+  {
+    v[i]=-1;
+  }
+  sro_ord *tmp_typ=(sro_ord *)omAlloc0(2*(n+r->N)*sizeof(sro_ord));
+  int typ_i=0;
+  int prev_ordsgn=0;
+
+  // fill in v, tmp_typ, tmp_ordsgn, determine typ_i (== ordSize)
+  int j=0;
+  int j_bits=BITS_PER_LONG;
+  BOOLEAN need_to_add_comp=FALSE;
+  for(i=0;i<n;i++)
+  {
+    tmp_typ[typ_i].order_index=i;
+    switch (r->order[i])
+    {
+      case ringorder_a:
+      case ringorder_aa:
+        rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,tmp_typ[typ_i],
+                   r->wvhdl[i]);
+        typ_i++;
+        break;
+
+      case ringorder_c:
+        rO_Align(j, j_bits);
+        rO_LexVars_neg(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
+        break;
+
+      case ringorder_C:
+        rO_Align(j, j_bits);
+        rO_LexVars(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
+        break;
+
+      case ringorder_M:
+        {
+          int k,l;
+          k=r->block1[i]-r->block0[i]+1; // number of vars
+          for(l=0;l<k;l++)
+          {
+            rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                       tmp_typ[typ_i],
+                       r->wvhdl[i]+(r->block1[i]-r->block0[i]+1)*l);
+            typ_i++;
+          }
+          break;
+        }
+
+      case ringorder_lp:
+        rO_LexVars(j, j_bits, r->block0[i],r->block1[i], prev_ordsgn,
+                   tmp_ordsgn,v,bits, -1);
+        break;
+
+      case ringorder_ls:
+        rO_LexVars_neg(j, j_bits, r->block0[i],r->block1[i], prev_ordsgn,
+                       tmp_ordsgn,v, bits, -1);
+        break;
+
+      case ringorder_rp:
+        rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i], prev_ordsgn,
+                       tmp_ordsgn,v, bits, -1);
+        break;
+
+      case ringorder_dp:
+        if (r->block0[i]==r->block1[i])
+        {
+          rO_LexVars(j, j_bits, r->block0[i],r->block0[i], prev_ordsgn,
+                     tmp_ordsgn,v, bits, -1);
+        }
+        else
+        {
+          rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                     tmp_typ[typ_i]);
+          typ_i++;
+          rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i]+1,
+                         prev_ordsgn,tmp_ordsgn,v,bits, r->block0[i]);
+        }
+        break;
+
+      case ringorder_Dp:
+        if (r->block0[i]==r->block1[i])
+        {
+          rO_LexVars(j, j_bits, r->block0[i],r->block0[i], prev_ordsgn,
+                     tmp_ordsgn,v, bits, -1);
+        }
+        else
+        {
+          rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                     tmp_typ[typ_i]);
+          typ_i++;
+          rO_LexVars(j, j_bits, r->block0[i],r->block1[i]-1, prev_ordsgn,
+                     tmp_ordsgn,v, bits, r->block1[i]);
+        }
+        break;
+
+      case ringorder_ds:
+        if (r->block0[i]==r->block1[i])
+        {
+          rO_LexVars_neg(j, j_bits,r->block0[i],r->block1[i],prev_ordsgn,
+                         tmp_ordsgn,v,bits, -1);
+        }
+        else
+        {
+          rO_TDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                         tmp_typ[typ_i]);
+          typ_i++;
+          rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i]+1,
+                         prev_ordsgn,tmp_ordsgn,v,bits, r->block0[i]);
+        }
+        break;
+
+      case ringorder_Ds:
+        if (r->block0[i]==r->block1[i])
+        {
+          rO_LexVars_neg(j, j_bits, r->block0[i],r->block0[i],prev_ordsgn,
+                         tmp_ordsgn,v, bits, -1);
+        }
+        else
+        {
+          rO_TDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                         tmp_typ[typ_i]);
+          typ_i++;
+          rO_LexVars(j, j_bits, r->block0[i],r->block1[i]-1, prev_ordsgn,
+                     tmp_ordsgn,v, bits, r->block1[i]);
+        }
+        break;
+
+      case ringorder_wp:
+        rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                   tmp_typ[typ_i], r->wvhdl[i]);
+        typ_i++;
+        if (r->block1[i]!=r->block0[i])
+        {
+          rO_LexVars_neg(j, j_bits,r->block1[i],r->block0[i]+1, prev_ordsgn,
+                         tmp_ordsgn, v,bits, r->block0[i]);
+        }
+        break;
+
+      case ringorder_Wp:
+        rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                   tmp_typ[typ_i], r->wvhdl[i]);
+        typ_i++;
+        if (r->block1[i]!=r->block0[i])
+        {
+          rO_LexVars(j, j_bits,r->block0[i],r->block1[i]-1, prev_ordsgn,
+                     tmp_ordsgn,v, bits, r->block1[i]);
+        }
+        break;
+
+      case ringorder_ws:
+        rO_WDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                       tmp_typ[typ_i], r->wvhdl[i]);
+        typ_i++;
+        if (r->block1[i]!=r->block0[i])
+        {
+          rO_LexVars_neg(j, j_bits,r->block1[i],r->block0[i]+1, prev_ordsgn,
+                         tmp_ordsgn, v,bits, r->block0[i]);
+        }
+        break;
+
+      case ringorder_Ws:
+        rO_WDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
+                       tmp_typ[typ_i], r->wvhdl[i]);
+        typ_i++;
+        if (r->block1[i]!=r->block0[i])
+        {
+          rO_LexVars(j, j_bits,r->block0[i],r->block1[i]-1, prev_ordsgn,
+                     tmp_ordsgn,v, bits, r->block1[i]);
+        }
+        break;
+
+      case ringorder_S:
+        rO_Syzcomp(j, j_bits,prev_ordsgn, tmp_ordsgn,tmp_typ[typ_i]);
+        need_to_add_comp=TRUE;
+        typ_i++;
+        break;
+
+      case ringorder_s:
+        rO_Syz(j, j_bits,prev_ordsgn, tmp_ordsgn,tmp_typ[typ_i]);
+        need_to_add_comp=TRUE;
+        typ_i++;
+        break;
+
+      case ringorder_unspec:
+      case ringorder_no:
+      default:
+        dReportError("undef. ringorder used\n");
+        break;
+    }
+  }
+
+  int j0=j; // save j
+  int j_bits0=j_bits; // save jbits
+  rO_Align(j,j_bits);
+  r->CmpL_Size = j;
+
+  j_bits=j_bits0; j=j0;
+
+  // fill in some empty slots with variables not already covered
+  // v0 is special, is therefore normally already covered
+  // now we do have rings without comp...
+  if((need_to_add_comp) && (v[0]== -1))
+  {
+    if (prev_ordsgn==1)
+    {
+      rO_Align(j, j_bits);
+      rO_LexVars(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
+    }
+    else
+    {
+      rO_Align(j, j_bits);
+      rO_LexVars_neg(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
+    }
+  }
+  // the variables
+  for(i=1 ; i<r->N+1 ; i++)
+  {
+    if(v[i]==(-1))
+    {
+      if (prev_ordsgn==1)
+      {
+        rO_LexVars(j, j_bits, i,i, prev_ordsgn,tmp_ordsgn,v,bits, -1);
+      }
+      else
+      {
+        rO_LexVars_neg(j,j_bits,i,i, prev_ordsgn,tmp_ordsgn,v,bits, -1);
+      }
+    }
+  }
+
+  rO_Align(j,j_bits);
+  // ----------------------------
+  // finished with constructing the monomial, computing sizes:
+
+  r->ExpL_Size=j;
+  r->PolyBin = omGetSpecBin(POLYSIZE + (r->ExpL_Size)*sizeof(long));
+  assume(r->PolyBin != NULL);
+
+  // ----------------------------
+  // indices and ordsgn vector for comparison
+  //
+  // r->pCompHighIndex already set
+  r->ordsgn=(long *)omAlloc0(r->ExpL_Size*sizeof(long));
+
+  for(j=0;j<r->CmpL_Size;j++)
+  {
+    r->ordsgn[j] = tmp_ordsgn[j];
+  }
+
+  omFreeSize((ADDRESS)tmp_ordsgn,(2*(n+r->N)*sizeof(long)));
+
+  // ----------------------------
+  // description of orderings for setm:
+  //
+  r->OrdSize=typ_i;
+  if (typ_i==0) r->typ=NULL;
+  else
+  {
+    r->typ=(sro_ord*)omAlloc(typ_i*sizeof(sro_ord));
+    memcpy(r->typ,tmp_typ,typ_i*sizeof(sro_ord));
+  }
+  omFreeSize((ADDRESS)tmp_typ,(2*(n+r->N)*sizeof(sro_ord)));
+
+  // ----------------------------
+  // indices for (first copy of ) variable entries in exp.e vector (VarOffset):
+  r->VarOffset=v;
+
+  // ----------------------------
+  // other indicies
+  r->pCompIndex=(r->VarOffset[0] & 0xffff); //r->VarOffset[0];
+  i=0; // position
+  j=0; // index in r->typ
+  if (i==r->pCompIndex) i++;
+  while ((j < r->OrdSize)
+         && ((r->typ[j].ord_typ==ro_syzcomp) ||
+             (r->typ[j].ord_typ==ro_syz) ||
+             (r->order[r->typ[j].order_index] == ringorder_aa)))
+  {
+    i++; j++;
+  }
+  if (i==r->pCompIndex) i++;
+  r->pOrdIndex=i;
+
+  // ----------------------------
+  rSetDegStuff(r);
+  rSetOption(r);
+  // ----------------------------
+  // r->p_Setm
+  r->p_Setm = p_GetSetmProc(r);
+
+  // ----------------------------
+  // set VarL_*
+  rSetVarL(r);
+
+  //  ----------------------------
+  // right-adjust VarOffset
+  rRightAdjustVarOffset(r);
+
+  // ----------------------------
+  // set NegWeightL*
+  rSetNegWeight(r);
+
+  // ----------------------------
+  // p_Procs: call AFTER NegWeightL
+  r->p_Procs = (p_Procs_s*)omAlloc(sizeof(p_Procs_s));
+  p_ProcsSet(r, r->p_Procs);
+
+  return FALSE;
+}
+
+void rUnComplete(ring r)
+{
+  if (r == NULL) return;
+  if (r->VarOffset != NULL)
+  {
+    if (r->PolyBin != NULL)
+      omUnGetSpecBin(&(r->PolyBin));
+
+    omFreeSize((ADDRESS)r->VarOffset, (r->N +1)*sizeof(int));
+    if (r->order != NULL)
+    {
+      if (r->order[0] == ringorder_s && r->typ[0].data.syz.limit > 0)
+      {
+        omFreeSize(r->typ[0].data.syz.syz_index,
+             (r->typ[0].data.syz.limit +1)*sizeof(int));
+      }
+    }
+    if (r->OrdSize!=0 && r->typ != NULL)
+    {
+      omFreeSize((ADDRESS)r->typ,r->OrdSize*sizeof(sro_ord));
+    }
+    if (r->ordsgn != NULL && r->CmpL_Size != 0)
+      omFreeSize((ADDRESS)r->ordsgn,r->ExpL_Size*sizeof(long));
+    if (r->p_Procs != NULL)
+      omFreeSize(r->p_Procs, sizeof(p_Procs_s));
+    omfreeSize(r->VarL_Offset, r->VarL_Size*sizeof(int));
+  }
+  if (r->NegWeightL_Offset!=NULL)
+  {
+    omFreeSize(r->NegWeightL_Offset, r->NegWeightL_Size*sizeof(int));
+    r->NegWeightL_Offset=NULL;
+  }
+}
+
+// set r->VarL_Size, r->VarL_Offset, r->VarL_LowIndex
+static void rSetVarL(ring r)
+{
+  int  min = INT_MAX, min_j = -1;
+  int* VarL_Number = (int*) omAlloc0(r->ExpL_Size*sizeof(int));
+
+  int i,j;
+
+  // count how often a var long is occupied by an exponent
+  for (i=1; i<=r->N; i++)
+  {
+    VarL_Number[r->VarOffset[i] & 0xffffff]++;
+  }
+
+  // determine how many and min
+  for (i=0, j=0; i<r->ExpL_Size; i++)
+  {
+    if (VarL_Number[i] != 0)
+    {
+      if (min > VarL_Number[i])
+      {
+        min = VarL_Number[i];
+        min_j = j;
+      }
+      j++;
+    }
+  }
+
+  r->VarL_Size = j;
+  r->VarL_Offset = (int*) omAlloc(r->VarL_Size*sizeof(int));
+  r->VarL_LowIndex = 0;
+
+  // set VarL_Offset
+  for (i=0, j=0; i<r->ExpL_Size; i++)
+  {
+    if (VarL_Number[i] != 0)
+    {
+      r->VarL_Offset[j] = i;
+      if (j > 0 && r->VarL_Offset[j-1] != r->VarL_Offset[j] - 1)
+        r->VarL_LowIndex = -1;
+      j++;
+    }
+  }
+  if (r->VarL_LowIndex >= 0)
+    r->VarL_LowIndex = r->VarL_Offset[0];
+
+  r->MinExpPerLong = min;
+  if (min_j != 0)
+  {
+    j = r->VarL_Offset[min_j];
+    r->VarL_Offset[min_j] = r->VarL_Offset[0];
+    r->VarL_Offset[0] = j;
+  }
+  omFree(VarL_Number);
+}
+
+static void rRightAdjustVarOffset(ring r)
+{
+  int* shifts = (int*) omAlloc(r->ExpL_Size*sizeof(int));
+  int i;
+  // initialize shifts
+  for (i=0;i<r->ExpL_Size;i++)
+    shifts[i] = BIT_SIZEOF_LONG;
+
+  // find minimal bit in each long var
+  for (i=1;i<=r->N;i++)
+  {
+    if (shifts[r->VarOffset[i] & 0xffffff] > r->VarOffset[i] >> 24)
+      shifts[r->VarOffset[i] & 0xffffff] = r->VarOffset[i] >> 24;
+  }
+  // reset r->VarOffset
+  for (i=1;i<=r->N;i++)
+  {
+    if (shifts[r->VarOffset[i] & 0xffffff] != 0)
+      r->VarOffset[i]
+        = (r->VarOffset[i] & 0xffffff) |
+        (((r->VarOffset[i] >> 24) - shifts[r->VarOffset[i] & 0xffffff]) << 24);
+  }
+  omFree(shifts);
+}
+
+// get r->divmask depending on bits per exponent
+static unsigned long rGetDivMask(int bits)
+{
+  unsigned long divmask = 1;
+  int i = bits;
+
+  while (i < BIT_SIZEOF_LONG)
+  {
+    divmask |= (((unsigned long) 1) << (unsigned long) i);
+    i += bits;
+  }
+  return divmask;
+}
+
+#ifdef RDEBUG
+void rDebugPrint(ring r)
+{
+  if (r==NULL)
+  {
+    PrintS("NULL ?\n");
+    return;
+  }
+  char *TYP[]={"ro_dp","ro_wp","ro_wp_neg","ro_cp",
+               "ro_syzcomp", "ro_syz", "ro_none"};
+  int i,j;
+
+  Print("ExpL_Size:%d ",r->ExpL_Size);
+  Print("CmpL_Size:%d ",r->CmpL_Size);
+  Print("VarL_Size:%d\n",r->VarL_Size);
+  Print("bitmask=0x%x (expbound=%d) \n",r->bitmask, r->bitmask);
+  Print("BitsPerExp=%d ExpPerLong=%d MinExpPerLong=%d at L[%d]\n", r->BitsPerExp, r->ExpPerLong, r->MinExpPerLong, r->VarL_Offset[0]);
+  PrintS("varoffset:\n");
+  if (r->VarOffset==NULL) PrintS(" NULL\n");
+  else
+    for(j=0;j<=r->N;j++)
+      Print("  v%d at e-pos %d, bit %d\n",
+            j,r->VarOffset[j] & 0xffffff, r->VarOffset[j] >>24);
+  Print("divmask=%p\n", r->divmask);
+  PrintS("ordsgn:\n");
+  for(j=0;j<r->CmpL_Size;j++)
+    Print("  ordsgn %d at pos %d\n",r->ordsgn[j],j);
+  Print("OrdSgn:%d\n",r->OrdSgn);
+  PrintS("ordrec:\n");
+  for(j=0;j<r->OrdSize;j++)
+  {
+    Print("  typ %s",TYP[r->typ[j].ord_typ]);
+    Print("  place %d",r->typ[j].data.dp.place);
+    if (r->typ[j].ord_typ!=ro_syzcomp)
+    {
+      Print("  start %d",r->typ[j].data.dp.start);
+      Print("  end %d",r->typ[j].data.dp.end);
+      if (r->typ[j].ord_typ==ro_wp)
+      {
+        Print(" w:");
+        int l;
+        for(l=r->typ[j].data.wp.start;l<=r->typ[j].data.wp.end;l++)
+          Print(" %d",r->typ[j].data.wp.weights[l-r->typ[j].data.wp.start]);
+      }
+    }
+    PrintLn();
+  }
+  Print("pOrdIndex:%d pCompIndex:%d\n", r->pOrdIndex, r->pCompIndex);
+  Print("OrdSize:%d\n",r->OrdSize);
+  PrintS("--------------------\n");
+  for(j=0;j<r->ExpL_Size;j++)
+  {
+    Print("L[%d]: ",j);
+    if (j< r->CmpL_Size)
+      Print("ordsgn %d ", r->ordsgn[j]);
+    else
+      PrintS("no comp ");
+    i=1;
+    for(;i<=r->N;i++)
+    {
+      if( (r->VarOffset[i] & 0xffffff) == j )
+      {  Print("v%d at e[%d], bit %d; ", i,r->VarOffset[i] & 0xffffff,
+                                         r->VarOffset[i] >>24 ); }
+    }
+    if( r->pCompIndex==j ) PrintS("v0; ");
+    for(i=0;i<r->OrdSize;i++)
+    {
+      if (r->typ[i].data.dp.place == j)
+      {
+        Print("ordrec:%s (start:%d, end:%d) ",TYP[r->typ[i].ord_typ],
+          r->typ[i].data.dp.start, r->typ[i].data.dp.end);
+      }
+    }
+
+    if (j==r->pOrdIndex)
+      PrintS("pOrdIndex\n");
+    else
+      PrintLn();
+  }
+
+  // p_Procs stuff
+  p_Procs_s proc_names;
+  char* field;
+  char* length;
+  char* ord;
+  p_Debug_GetProcNames(r, &proc_names);
+  p_Debug_GetSpecNames(r, field, length, ord);
+
+  Print("p_Spec  : %s, %s, %s\n", field, length, ord);
+  PrintS("p_Procs :\n");
+  for (i=0; i<(int) (sizeof(p_Procs_s)/sizeof(void*)); i++)
+  {
+    Print(" %s,\n", ((char**) &proc_names)[i]);
+  }
+}
+
+void pDebugPrintR(poly p, ring r)
+{
+  int i,j;
+  pWrite(p);
+  j=2;
+  while(p!=NULL)
+  {
+    Print("\nexp[0..%d]\n",r->ExpL_Size-1);
+    for(i=0;i<r->ExpL_Size;i++)
+      Print("%d ",p->exp[i]);
+    PrintLn();
+    Print("v0:%d ",p_GetComp(p, r));
+    for(i=1;i<=r->N;i++) Print(" v%d:%d",i,p_GetExp(p,i, r));
+    PrintLn();
+    pIter(p);
+    j--;
+    if (j==0) { PrintS("...\n"); break; }
+  }
+}
+
+void pDebugPrint(poly p)
+{
+  pDebugPrintR(p, currRing);
+}
+#endif // RDEBUG
+
+
+/*2
+* asssume that rComplete was called with r
+* assume that the first block ist ringorder_S
+* change the block to reflect the sequence given by appending v
+*/
+
+#ifdef PDEBUG
+void rDBChangeSComps(int* currComponents,
+                     long* currShiftedComponents,
+                     int length,
+                     ring r)
+{
+  r->typ[1].data.syzcomp.length = length;
+  rNChangeSComps( currComponents, currShiftedComponents, r);
+}
+void rDBGetSComps(int** currComponents,
+                 long** currShiftedComponents,
+                 int *length,
+                 ring r)
+{
+  *length = r->typ[1].data.syzcomp.length;
+  rNGetSComps( currComponents, currShiftedComponents, r);
+}
+#endif
+
+void rNChangeSComps(int* currComponents, long* currShiftedComponents, ring r)
+{
+  assume(r->order[1]==ringorder_S);
+
+  r->typ[1].data.syzcomp.ShiftedComponents = currShiftedComponents;
+  r->typ[1].data.syzcomp.Components = currComponents;
+}
+
+void rNGetSComps(int** currComponents, long** currShiftedComponents, ring r)
+{
+  assume(r->order[1]==ringorder_S);
+
+  *currShiftedComponents = r->typ[1].data.syzcomp.ShiftedComponents;
+  *currComponents =   r->typ[1].data.syzcomp.Components;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// The following routines all take as input a ring r, and return R
+// where R has a certain property. P might be equal r in which case r
+// had already this property
+//
+// Without argument, these functions work on currRing and change it,
+// if necessary
+
+// for the time being, this is still here
+static ring rAssure_SyzComp(ring r, BOOLEAN complete = TRUE);
+
+ring rCurrRingAssure_SyzComp()
+{
+  ring r = rAssure_SyzComp(currRing);
+  if (r != currRing)
+  {
+    ring old_ring = currRing;
+    rChangeCurrRing(r);
+    if (old_ring->qideal != NULL)
+    {
+      r->qideal = idrCopyR_NoSort(old_ring->qideal, old_ring);
+      assume(idRankFreeModule(r->qideal) == 0);
+      currQuotient = r->qideal;
+    }
+  }
+  return r;
+}
+
+static ring rAssure_SyzComp(ring r, BOOLEAN complete)
+{
+  if (r->order[0] == ringorder_s) return r;
+  ring res=rCopy0(r, FALSE, FALSE);
+  int i=rBlocks(r);
+  int j;
+
+  res->order=(int *)omAlloc0((i+1)*sizeof(int));
+  for(j=i;j>0;j--) res->order[j]=r->order[j-1];
+  res->order[0]=ringorder_s;
+
+  res->block0=(int *)omAlloc0((i+1)*sizeof(int));
+  for(j=i;j>0;j--) res->block0[j]=r->block0[j-1];
+
+  res->block1=(int *)omAlloc0((i+1)*sizeof(int));
+  for(j=i;j>0;j--) res->block1[j]=r->block1[j-1];
+
+  int ** wvhdl =(int **)omAlloc0((i+1)*sizeof(int**));
+  for(j=i;j>0;j--)
+  {
+    if (r->wvhdl[j-1] != NULL)
+    {
+      wvhdl[j] = (int*) omMemDup(r->wvhdl[j-1]);
+    }
+  }
+  res->wvhdl = wvhdl;
+
+  if (complete) rComplete(res, 1);
+  return res;
+}
+
+static ring rAssure_CompLastBlock(ring r, BOOLEAN complete = TRUE)
+{
+  int last_block = rBlocks(r) - 2;
+  if (r->order[last_block] != ringorder_c &&
+      r->order[last_block] != ringorder_C)
+  {
+    int c_pos = 0;
+    int i;
+
+    for (i=0; i< last_block; i++)
+    {
+      if (r->order[i] == ringorder_c || r->order[i] == ringorder_C)
+      {
+        c_pos = i;
+        break;
+      }
+    }
+    if (c_pos != -1)
+    {
+      ring new_r = rCopy0(r, FALSE, TRUE);
+      for (i=c_pos+1; i<=last_block; i++)
+      {
+        new_r->order[i-1] = new_r->order[i];
+        new_r->block0[i-1] = new_r->block0[i];
+        new_r->block1[i-1] = new_r->block1[i];
+        new_r->wvhdl[i-1] = new_r->wvhdl[i];
+      }
+      new_r->order[last_block] = r->order[c_pos];
+      new_r->block0[last_block] = r->block0[c_pos];
+      new_r->block1[last_block] = r->block1[c_pos];
+      new_r->wvhdl[last_block] = r->wvhdl[c_pos];
+      if (complete) rComplete(new_r, 1);
+      return new_r;
+    }
+  }
+  return r;
+}
+
+ring rCurrRingAssure_CompLastBlock()
+{
+  ring new_r = rAssure_CompLastBlock(currRing);
+  if (currRing != new_r)
+  {
+    ring old_r = currRing;
+    rChangeCurrRing(new_r);
+    if (old_r->qideal != NULL)
+    {
+      new_r->qideal = idrCopyR(old_r->qideal, old_r);
+      currQuotient = new_r->qideal;
+    }
+  }
+  return new_r;
+}
+
+ring rCurrRingAssure_SyzComp_CompLastBlock()
+{
+  ring new_r_1 = rAssure_CompLastBlock(currRing, FALSE);
+  ring new_r = rAssure_SyzComp(new_r_1, FALSE);
+
+  if (new_r != currRing)
+  {
+    ring old_r = currRing;
+    if (new_r_1 != new_r && new_r_1 != old_r) rDelete(new_r_1);
+    rComplete(new_r, 1);
+    rChangeCurrRing(new_r);
+    if (old_r->qideal != NULL)
+    {
+      new_r->qideal = idrCopyR(old_r->qideal, old_r);
+      currQuotient = new_r->qideal;
+    }
+    rTest(new_r);
+    rTest(old_r);
+  }
+  return new_r;
+}
+
+// use this for global orderings consisting of two blocks
+static ring rCurrRingAssure_Global(rRingOrder_t b1, rRingOrder_t b2)
+{
+  int r_blocks = rBlocks(currRing);
+  int i;
+
+  assume(b1 == ringorder_c || b1 == ringorder_C ||
+         b2 == ringorder_c || b2 == ringorder_C ||
+         b2 == ringorder_S);
+  if ((r_blocks == 3) &&
+      (currRing->order[0] == b1) &&
+      (currRing->order[1] == b2) &&
+      (currRing->order[2] == 0))
+    return currRing;
+  ring res = rCopy0(currRing, TRUE, FALSE);
+  res->order = (int*)omAlloc0(3*sizeof(int));
+  res->block0 = (int*)omAlloc0(3*sizeof(int));
+  res->block1 = (int*)omAlloc0(3*sizeof(int));
+  res->wvhdl = (int**)omAlloc0(3*sizeof(int*));
+  res->order[0] = b1;
+  res->order[1] = b2;
+  if (b1 == ringorder_c || b1 == ringorder_C)
+  {
+    res->block0[1] = 1;
+    res->block1[1] = currRing->N;
+  }
+  else
+  {
+    res->block0[0] = 1;
+    res->block1[0] = currRing->N;
+  }
+  // HANNES: This sould be set in rComplete
+  res->OrdSgn = 1;
+  rComplete(res, 1);
+  rChangeCurrRing(res);
+  return res;
+}
+
+
+ring rCurrRingAssure_dp_S()
+{
+  return rCurrRingAssure_Global(ringorder_dp, ringorder_S);
+}
+
+ring rCurrRingAssure_dp_C()
+{
+  return rCurrRingAssure_Global(ringorder_dp, ringorder_C);
+}
+
+ring rCurrRingAssure_C_dp()
+{
+  return rCurrRingAssure_Global(ringorder_C, ringorder_dp);
+}
+
+
+void rSetSyzComp(int k)
+{
+  if (TEST_OPT_PROT) Print("{%d}", k);
+  if ((currRing->typ!=NULL) && (currRing->typ[0].ord_typ==ro_syz))
+  {
+    assume(k > currRing->typ[0].data.syz.limit);
+    int i;
+    if (currRing->typ[0].data.syz.limit == 0)
+    {
+      currRing->typ[0].data.syz.syz_index = (int*) omAlloc0((k+1)*sizeof(int));
+      currRing->typ[0].data.syz.syz_index[0] = 0;
+      currRing->typ[0].data.syz.curr_index = 1;
+    }
+    else
+    {
+      currRing->typ[0].data.syz.syz_index = (int*)
+        omReallocSize(currRing->typ[0].data.syz.syz_index,
+                (currRing->typ[0].data.syz.limit+1)*sizeof(int),
+                (k+1)*sizeof(int));
+    }
+    for (i=currRing->typ[0].data.syz.limit + 1; i<= k; i++)
+    {
+      currRing->typ[0].data.syz.syz_index[i] =
+        currRing->typ[0].data.syz.curr_index;
+    }
+    currRing->typ[0].data.syz.limit = k;
+    currRing->typ[0].data.syz.curr_index++;
+  }
+  else if ((currRing->order[0]!=ringorder_c) && (k!=0))
+  {
+    dReportError("syzcomp in incompatible ring");
+  }
+#ifdef PDEBUG
+  extern int pDBsyzComp;
+  pDBsyzComp=k;
+#endif
+}
+
+// return the max-comonent wchich has syzIndex i
+int rGetMaxSyzComp(int i)
+{
+  if ((currRing->typ!=NULL) && (currRing->typ[0].ord_typ==ro_syz) &&
+      currRing->typ[0].data.syz.limit > 0 && i > 0)
+  {
+    assume(i <= currRing->typ[0].data.syz.limit);
+    int j;
+    for (j=0; j<currRing->typ[0].data.syz.limit; j++)
+    {
+      if (currRing->typ[0].data.syz.syz_index[j] == i  &&
+          currRing->typ[0].data.syz.syz_index[j+1] != i)
+      {
+        assume(currRing->typ[0].data.syz.syz_index[j+1] == i+1);
+        return j;
+      }
+    }
+    return currRing->typ[0].data.syz.limit;
+  }
+  else
+  {
+    return 0;
+  }
+}
+
+BOOLEAN rRing_is_Homog(ring r)
+{
+  if (r == NULL) return FALSE;
+  int i, j, nb = rBlocks(r);
+  for (i=0; i<nb; i++)
+  {
+    if (r->wvhdl[i] != NULL)
+    {
+      int length = r->block1[i] - r->block0[i];
+      int* wvhdl = r->wvhdl[i];
+      if (r->order[i] == ringorder_M) length *= length;
+      assume(omSizeOfAddr(wvhdl) >= length*sizeof(int));
+
+      for (j=0; j< length; j++)
+      {
+        if (wvhdl[j] != 0 && wvhdl[j] != 1) return FALSE;
+      }
+    }
+  }
+  return TRUE;
+}
+
+BOOLEAN rRing_has_CompLastBlock(ring r)
+{
+  assume(r != NULL);
+  int lb = rBlocks(r) - 2;
+  return (r->order[lb] == ringorder_c || r->order[lb] == ringorder_C);
+}
+
+n_coeffType rFieldType(ring r)
+{
+  if (rField_is_Zp(r))     return n_Zp;
+  if (rField_is_Q(r))      return n_Q;
+  if (rField_is_R(r))      return n_R;
+  if (rField_is_GF(r))     return n_GF;
+  if (rField_is_long_R(r)) return n_long_R;
+  if (rField_is_Zp_a(r))   return n_Zp_a;
+  if (rField_is_Q_a(r))    return n_Q_a;
+  if (rField_is_long_C(r)) return n_long_C;
+  return n_unknown;
+}
+
+int * rGetWeightVec(ring r)
+{
+  assume(r!=NULL);
+  assume(r->OrdSize>0);
+  assume(r->typ[0].ord_typ==ro_wp);
+  return (r->typ[0].data.wp.weights);
+}
+
+void rSetWeightVec(ring r, int *wv)
+{
+  assume(r!=NULL);
+  assume(r->OrdSize>0);
+  assume(r->typ[0].ord_typ==ro_wp);
+  memcpy(r->typ[0].data.wp.weights,wv,r->N*sizeof(int));
+}
+
Index: kernel/ring.h
===================================================================
--- kernel/ring.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/ring.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,283 @@
+#ifndef RING_H
+#define RING_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT - the interpreter related ring operations
+*/
+/* $Id: ring.h,v 1.1.1.1 2003-10-06 12:15:52 Singular Exp $ */
+
+/* includes */
+#include "structs.h"
+#include "structs.h"  // we need ABS
+#include "polys-impl.h"
+
+#define SHORT_REAL_LENGTH 6 // use short reals for real <= 6 digits
+
+
+void   rChangeCurrRing(ring r);
+void   rSetHdl(idhdl h);
+ring   rInit(sleftv* pn, sleftv* rv, sleftv* ord);
+idhdl  rDefault(char *s);
+ring   rDefault(int ch, int N, char **n);
+#define rIsRingVar(A) r_IsRingVar(A,currRing)
+int    r_IsRingVar(char *n, ring r);
+void   rWrite(ring r);
+void   rKill(idhdl h);
+void   rKill(ring r);
+ring   rCopy(ring r);
+
+
+
+#ifdef PDEBUG
+#define rChangeSComps(c,s,l) rDBChangeSComps(c,s,l)
+#define rGetSComps(c,s,l) rDBGetSComps(c,s,l)
+void rDBChangeSComps(int* currComponents,
+                     long* currShiftedComponents,
+                     int length,
+                     ring r = currRing);
+void rDBGetSComps(int** currComponents,
+                  long** currShiftedComponents,
+                  int *length,
+                  ring r = currRing);
+#else
+#define rChangeSComps(c,s,l) rNChangeSComps(c,s)
+#define rGetSComps(c,s,l) rNGetSComps(c,s)
+#endif
+
+void rNChangeSComps(int* currComponents, long* currShiftedComponents, ring r = currRing);
+void rNGetSComps(int** currComponents, long** currShiftedComponents, ring r = currRing);
+
+idhdl  rFindHdl(ring r, idhdl n, idhdl w);
+idhdl rSimpleFindHdl(ring r, idhdl root, idhdl n);
+const char * rSimpleOrdStr(int ord);
+int rOrderName(char * ordername);
+char * rOrdStr(ring r);
+char * rVarStr(ring r);
+char * rCharStr(ring r);
+char * rString(ring r);
+int    rChar(ring r=currRing);
+#define rPar(r) (r->P)
+char * rParStr(ring r);
+int    rIsExtension(ring r);
+int    rIsExtension();
+int    rSum(ring r1, ring r2, ring &sum);
+
+BOOLEAN rEqual(ring r1, ring r2, BOOLEAN qr = 1);
+void   rUnComplete(ring r);
+
+#define  rInternalChar(r) ((r)->ch)
+
+BOOLEAN rRing_is_Homog(ring r=currRing);
+BOOLEAN rRing_has_CompLastBlock(ring r=currRing);
+
+inline BOOLEAN rField_is_Zp(ring r=currRing)
+{ return (r->ch > 1) && (r->parameter==NULL); }
+
+inline BOOLEAN rField_is_Zp(ring r, int p)
+{ return (r->ch > 1 && r->ch == ABS(p) && r->parameter==NULL); }
+
+inline BOOLEAN rField_is_Q(ring r=currRing)
+{ return (r->ch == 0) && (r->parameter==NULL); }
+
+inline BOOLEAN rField_is_numeric(ring r=currRing) /* R, long R, long C */
+{ return (r->ch ==  -1); }
+
+inline BOOLEAN rField_is_R(ring r=currRing)
+{
+  if (rField_is_numeric(r) && (r->float_len <= (short)SHORT_REAL_LENGTH))
+    return (r->parameter==NULL);
+  return FALSE;
+}
+
+inline BOOLEAN rField_is_GF(ring r=currRing)
+{ return (r->ch > 1) && (r->parameter!=NULL); }
+
+inline BOOLEAN rField_is_GF(ring r, int q)
+{ return (r->ch == q); }
+
+inline BOOLEAN rField_is_Zp_a(ring r=currRing)
+{ return (r->ch < -1); }
+
+inline BOOLEAN rField_is_Zp_a(ring r, int p)
+{ return (r->ch < -1 ) && (-(r->ch) == ABS(p)); }
+
+inline BOOLEAN rField_is_Q_a(ring r=currRing)
+{ return (r->ch == 1); }
+
+inline BOOLEAN rField_is_long_R(ring r=currRing)
+{
+  if (rField_is_numeric(r) && (r->float_len >(short)SHORT_REAL_LENGTH))
+    return (r->parameter==NULL);
+  return FALSE;
+}
+
+inline BOOLEAN rField_is_long_C(ring r=currRing)
+{
+  if (rField_is_numeric(r))
+    return (r->parameter!=NULL);
+  return FALSE;
+}
+
+inline BOOLEAN rField_has_simple_inverse(ring r=currRing)
+/* { return (r->ch>1) || (r->ch== -1); } *//* Z/p, GF(p,n), R, long_R, long_C*/
+{ return (r->ch>1) || ((r->ch== -1) && (r->float_len < 10)); } /* Z/p, GF(p,n), R, long_R, long_C*/
+
+inline BOOLEAN rField_has_simple_Alloc(ring r=currRing)
+{ return (rField_is_Zp(r) || rField_is_GF(r) || rField_is_R(r)); }
+
+/* Z/p, GF(p,n), R: nCopy, nNew, nDelete are dummies*/
+inline BOOLEAN rField_is_Extension(ring r=currRing)
+{ return (rField_is_Q_a(r)) || (rField_is_Zp_a(r)); } /* Z/p(a) and Q(a)*/
+
+n_coeffType rFieldType(ring r);
+
+// this needs to be called whenever a new ring is created: new fields
+// in ring are created (like VarOffset), unless they already exist
+// with force == 1, new fields are _always_ created (overwritten),
+// even if they exist
+BOOLEAN rComplete(ring r, int force = 0);
+// use this to free fields created by rComplete
+void rUnComplete(ring r);
+inline int rBlocks(ring r)
+{
+  int i=0;
+  while (r->order[i]!=0) i++;
+  return i+1;
+}
+
+// misc things
+inline char* rRingVar(short i)
+{
+  return currRing->names[i];
+}
+inline char* rRingVar(short i, ring r)
+{
+  return r->names[i];
+}
+inline BOOLEAN rShortOut(ring r)
+{
+  return (r->ShortOut);
+}
+
+// order stuff
+typedef enum rRingOrder_t
+{
+  ringorder_no = 0,
+  ringorder_a,
+  ringorder_c,
+  ringorder_C,
+  ringorder_M,
+  ringorder_S,
+  ringorder_s,
+  ringorder_lp,
+  ringorder_dp,
+  ringorder_rp,
+  ringorder_Dp,
+  ringorder_wp,
+  ringorder_Wp,
+  ringorder_ls,
+  ringorder_ds,
+  ringorder_Ds,
+  ringorder_ws,
+  ringorder_Ws,
+  ringorder_L,
+  // the following are only used internally
+  ringorder_aa, // for idElimination, like a, except pFDeg, pWeigths ignore it
+  ringorder_unspec
+} rRingOrder_t;
+
+typedef enum rOrderType_t
+{
+  rOrderType_General = 0, // non-simple ordering as specified by currRing
+  rOrderType_CompExp,     // simple ordering, component has priority
+  rOrderType_ExpComp,     // simple ordering, exponent vector has priority
+                          // component not compatible with exp-vector order
+  rOrderType_Exp,         // simple ordering, exponent vector has priority
+                          // component is compatible with exp-vector order
+  rOrderType_Syz,         // syzygy ordering
+  rOrderType_Schreyer,    // Schreyer ordering
+  rOrderType_Syz2dpc,     // syzcomp2dpc
+  rOrderType_ExpNoComp    // simple ordering, differences in component are
+                          // not considered
+} rOrderType_t;
+
+inline BOOLEAN rIsSyzIndexRing(ring r)
+{ return r->order[0] == ringorder_s;}
+
+inline int rGetCurrSyzLimit(ring r = currRing)
+{ return (r->order[0] == ringorder_s ?
+          r->typ[0].data.syz.limit : 0);}
+
+// Ring Manipulations
+ring   rCurrRingAssure_SyzComp();
+void   rSetSyzComp(int k);
+ring   rCurrRingAssure_dp_S();
+ring   rCurrRingAssure_dp_C();
+ring   rCurrRingAssure_C_dp();
+// makes sure that c/C ordering is last ordering
+ring   rCurrRingAssure_CompLastBlock();
+// makes sure that c/C ordering is last ordering and SyzIndex is first
+ring   rCurrRingAssure_SyzComp_CompLastBlock();
+
+// return the max-comonent wchich has syzIndex i
+// Assume: i<= syzIndex_limit
+int rGetMaxSyzComp(int i);
+
+BOOLEAN rHasSimpleOrder(ring r);
+// returns TRUE, if simple lp or ls ordering
+BOOLEAN rHasSimpleLexOrder(ring r);
+// return TRUE if p->exp[r->pOrdIndex] holds total degree of p */
+BOOLEAN rOrd_is_Totaldegree_Ordering(ring r =currRing);
+// return TRUE if p_SetComp requires p_Setm
+BOOLEAN rOrd_SetCompRequiresSetm(ring r);
+rOrderType_t    rGetOrderType(ring r);
+/* returns TRUE if var(i) belongs to p-block */
+BOOLEAN rIsPolyVar(int i, ring r = currRing);
+
+inline BOOLEAN rOrd_is_Comp_dp(ring r)
+{
+  return ((r->order[0] == ringorder_c || r->order[0] == ringorder_C) &&
+          r->order[1] == ringorder_dp &&
+          r->order[2] == 0);
+}
+
+#ifdef HAVE_PLURAL
+inline BOOLEAN rIsPluralRing(ring r)
+{
+  return r->nc != NULL;
+}
+#else
+#define rIsPluralRing(r)  (0)
+#endif
+
+#ifdef RDEBUG
+#define rTest(r)    rDBTest(r, __FILE__, __LINE__)
+extern BOOLEAN rDBTest(ring r, char* fn, int l);
+#else
+#define rTest(r)
+#endif
+
+ring rModifyRing(ring r, BOOLEAN omit_degree,
+                         BOOLEAN omit_comp,
+                         unsigned long exp_limit);
+// construct Wp, C ring
+ring rModifyRing_Wp(ring r, int* weights);
+
+void rKillModifiedRing(ring r);
+// also frees weights
+void rKillModified_Wp_Ring(ring r);
+
+ring rModifyRing_Simple(ring r, BOOLEAN omit_degree, BOOLEAN omit_comp, unsigned long exp_limit, BOOLEAN &simple);
+void rKillModifiedRing_Simple(ring r);
+
+void rDebugPrint(ring r);
+void pDebugPrint(poly p);
+
+int * rGetWeightVec(ring r);
+void rSetWeightVec(ring r, int *);
+
+lists rDecompose(ring r);
+ring rCompose(lists  L);
+#endif
Index: kernel/run.h
===================================================================
--- kernel/run.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/run.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,100 @@
+// #define DEBUG
+// #define DEBUGALL
+
+// B19 - egcs automatically defines CYGWIN32 but not CYGWIN
+// B20 - egcs automatically defines both CYGWIN32 and CYGWIN
+// Bfuture - (???) defines CYGWIN but not CYGWIN32
+#if defined(__CYGWIN32__)
+#if !defined(__CYGWIN__)
+ #define B19
+ #define __CYGWIN__
+#else
+ #define B20
+#endif
+#else
+#if defined(__CYGWIN__)
+ #define B21
+#endif
+#endif
+// Now: use __CYGWIN__ to represent any version
+// distinguish using B19, B20, or B21
+
+#if defined(__CYGWIN__)
+#ifdef B19
+#define CYGWIN_ATTACH_HANDLE_TO_FD(a)      cygwin32_attach_handle_to_fd      a
+#define CYGWIN_CONV_TO_FULL_POSIX_PATH(a)  cygwin32_conv_to_full_posix_path  a
+#define CYGWIN_CONV_TO_FULL_WIN32_PATH(a)  cygwin32_conv_to_full_win32_path  a
+#define CYGWIN_CONV_TO_POSIX_PATH(a)       cygwin32_conv_to_posix_path       a
+#define CYGWIN_CONV_TO_WIN32_PATH(a)       cygwin32_conv_to_win32_path       a
+#define CYGWIN_DETACH_DLL(a)               cygwin32_detach_dll               a
+#define CYGWIN_GETSHARED(a)                cygwin32_getshared                a
+#define CYGWIN_INTERNAL(a)                 cygwin32_internal                 a
+#define CYGWIN_POSIX_PATH_LIST_P(a)        cygwin32_posix_path_list_p        a
+#define CYGWIN_POSIX_TO_WIN32_PATH_LIST(a) cygwin32_posix_to_win32_path_list a
+#define CYGWIN_POSIX_TO_WIN32_PATH_LIST_BUF_SIZE(a) cygwin32_posix_to_win32_path_list_buf_size a
+#define CYGWIN_SPLIT_PATH(a)               cygwin32_split_path               a
+#define CYGWIN_WIN32_TO_POSIX_PATH_LIST(a) cygwin32_win32_to_posix_path_list a
+#define CYGWIN_WIN32_TO_POSIX_PATH_LIST_BUF_SIZE(a) cygwin32_win32_to_posix_path_list_buf_size a
+#define CYGWIN_WINPID_TO_PID(a)            cygwin32_winpid_to_pid            a
+#else
+#define CYGWIN_ATTACH_HANDLE_TO_FD(a)      cygwin_attach_handle_to_fd      a
+#define CYGWIN_CONV_TO_FULL_POSIX_PATH(a)  cygwin_conv_to_full_posix_path  a
+#define CYGWIN_CONV_TO_FULL_WIN32_PATH(a)  cygwin_conv_to_full_win32_path  a
+#define CYGWIN_CONV_TO_POSIX_PATH(a)       cygwin_conv_to_posix_path       a
+#define CYGWIN_CONV_TO_WIN32_PATH(a)       cygwin_conv_to_win32_path       a
+#define CYGWIN_DETACH_DLL(a)               cygwin_detach_dll               a
+#define CYGWIN_GETSHARED(a)                cygwin_getshared                a
+#define CYGWIN_INTERNAL(a)                 cygwin_internal                 a
+#define CYGWIN_POSIX_PATH_LIST_P(a)        cygwin_posix_path_list_p        a
+#define CYGWIN_POSIX_TO_WIN32_PATH_LIST(a) cygwin_posix_to_win32_path_list a
+#define CYGWIN_POSIX_TO_WIN32_PATH_LIST_BUF_SIZE(a) cygwin_posix_to_win32_path_list_buf_size a
+#define CYGWIN_SPLIT_PATH(a)               cygwin_split_path               a
+#define CYGWIN_WIN32_TO_POSIX_PATH_LIST(a) cygwin_win32_to_posix_path_list a
+#define CYGWIN_WIN32_TO_POSIX_PATH_LIST_BUF_SIZE(a) cygwin_win32_to_posix_path_list_buf_size a
+#define CYGWIN_WINPID_TO_PID(a)            cygwin_winpid_to_pid            a
+#endif
+#endif
+
+#if defined(__CYGWIN__)
+ #define PATH_SEP_CHAR_STR "/"
+ #define SEP_CHARS ":"
+#else
+ #define PATH_SEP_CHAR_STR "\\"
+ #define SEP_CHARS ";"
+#endif
+
+#ifndef RC_INVOKED
+
+#define MAX_ARGS 20
+
+#ifdef DEBUG
+ #define Trace(x)   Trace_ x
+#else
+ #define Trace(x)
+#endif
+
+#define NUM_EXTENSIONS 2
+const char* exts[NUM_EXTENSIONS] = { "", ".exe" };
+
+char* pfopen(char *retval, const char *name, const char *dirs);
+void error(char* fmt, ...);
+void message(char* fmt, ...);
+void Trace_(char* fmt, ...);
+int get_exec_name_and_path(char* execname, char* execpath);
+char* my_strtok(char* s, const char* delim, char** lasts);
+int parse_cmdline_to_arg_array(char* argv[MAX_ARGS], char* cmdline);
+void strip_exe(char* s);
+int start_child(char* cmdline, int wait_for_child);
+void xemacs_special(char* exec);
+int build_cmdline(char* new_cmdline, char* exec, int argc, char* argv[]);
+void process_execname(char *exec, const char* execname, const char* execpath);
+int fileExists(char* fullname, const char* path, const char* name);
+int endsWith(const char* s1, const char* s2);
+int fileExistsMulti(char* fullname, const char* path,
+                    const char* name_noext, const char* exts[],
+                    const int extcnt);
+
+#endif /* RC_INVOKED */
+
+
+
Index: kernel/sbuckets.cc
===================================================================
--- kernel/sbuckets.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/sbuckets.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,303 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    sbuckets.cc
+ *  Purpose: implementation of routines for sorting polys using
+ *           a bucket sort
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 9/00
+ *  Version: $Id: sbuckets.cc,v 1.1.1.1 2003-10-06 12:16:02 Singular Exp $
+ *******************************************************************/
+#include "mod2.h"
+
+#include "sbuckets.h"
+#include "omalloc.h"
+#include "ring.h"
+#include "p_Procs.h"
+#include "p_polys.h"
+
+
+
+//////////////////////////////////////////////////////////////////////////
+// Declarations
+//
+
+class sBucketPoly
+{
+public:
+  poly p;
+  long length;
+};
+
+class sBucket
+{
+public:
+  ring          bucket_ring;
+  long          max_bucket;
+  sBucketPoly   buckets[BIT_SIZEOF_LONG - 3];
+}
+;
+
+static omBin sBucket_bin = omGetSpecBin(sizeof(sBucket));
+
+/////////////////////////////////////////////////////////////////////////////
+// internal routines
+//
+// returns floor(log_2(i))
+inline int LOG2(int i)
+{
+  assume (i > 0);
+  int j = 0;
+
+  do
+  {
+    i = i >> 1;
+    if (i == 0) return j;
+    j++;
+  }
+  while (1);
+
+  return j;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Creation/Destruction of buckets
+//
+sBucket_pt    sBucketCreate(ring r)
+{
+  sBucket_pt bucket = (sBucket_pt) omAlloc0Bin(sBucket_bin);
+  bucket->bucket_ring = r;
+  return bucket;
+}
+
+void          sBucketDestroy(sBucket_pt *bucket)
+{
+  assume(bucket != NULL);
+  omFreeBin(*bucket, sBucket_bin);
+  *bucket = NULL;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Convertion from/to SBpolys
+//
+
+static void sBucket_Merge_m(sBucket_pt bucket, poly p)
+{
+  assume(p != NULL && pNext(p) == NULL);
+  int length = 1;
+  int i = 0;
+
+  while (bucket->buckets[i].p != NULL)
+  {
+    p = p_Merge_q(p, bucket->buckets[i].p, bucket->bucket_ring);
+    length += bucket->buckets[i].length;
+    bucket->buckets[i].p = NULL;
+    bucket->buckets[i].length = 0;
+    i++;
+    assume(LOG2(length) == i);
+  }
+
+  bucket->buckets[i].p = p;
+  bucket->buckets[i].length = length;
+  if (i > bucket->max_bucket) bucket->max_bucket = i;
+}
+
+void sBucket_Merge_p(sBucket_pt bucket, poly p, int length)
+{
+  assume(bucket != NULL);
+  assume(length <= 0 || length == pLength(p));
+
+  if (p == NULL) return;
+  if (length <= 0) length = pLength(p);
+
+  int i = LOG2(length);
+
+  while (bucket->buckets[i].p != NULL)
+  {
+    p = p_Merge_q(p, bucket->buckets[i].p, bucket->bucket_ring);
+    length += bucket->buckets[i].length;
+    bucket->buckets[i].p = NULL;
+    bucket->buckets[i].length = 0;
+    i++;
+    assume(LOG2(length) == i);
+  }
+
+  bucket->buckets[i].p = p;
+  bucket->buckets[i].length = length;
+  if (i > bucket->max_bucket) bucket->max_bucket = i;
+}
+
+void sBucket_Add_p(sBucket_pt bucket, poly p, int length)
+{
+  assume(bucket != NULL);
+  assume(length <= 0 || length == pLength(p));
+
+  if (p == NULL) return;
+  if (length <= 0) length = pLength(p);
+
+  int i = LOG2(length);
+
+  while (bucket->buckets[i].p != NULL)
+  {
+    p = p_Add_q(p, bucket->buckets[i].p, length, bucket->buckets[i].length,
+                bucket->bucket_ring);
+    bucket->buckets[i].p = NULL;
+    bucket->buckets[i].length = 0;
+    i = LOG2(length);
+  }
+
+  bucket->buckets[i].p = p;
+  bucket->buckets[i].length = length;
+  if (i > bucket->max_bucket) bucket->max_bucket = i;
+}
+
+// Converts SBpoly into a poly and clears bucket
+// i.e., afterwards SBpoly == 0
+void sBucketClearMerge(sBucket_pt bucket, poly *p, int *length)
+{
+  poly pr = NULL;
+  int  lr = 0;
+  int i = 0;
+
+  while (bucket->buckets[i].p == NULL)
+  {
+    i++;
+    if (i > bucket->max_bucket) goto done;
+  }
+
+  pr = bucket->buckets[i].p;
+  lr = bucket->buckets[i].length;
+  bucket->buckets[i].p = NULL;
+  bucket->buckets[i].length = 0;
+  i++;
+
+  while (i <= bucket->max_bucket)
+  {
+    if (bucket->buckets[i].p != NULL)
+    {
+      pr = p_Merge_q(pr, bucket->buckets[i].p,bucket->bucket_ring);
+      lr += bucket->buckets[i].length;
+      bucket->buckets[i].p = NULL;
+      bucket->buckets[i].length = 0;
+    }
+    i++;
+  }
+
+  done:
+  *p = pr;
+  *length = lr;
+  bucket->max_bucket = 0;
+}
+
+// Converts SBpoly into a poly and clears bucket
+// i.e., afterwards SBpoly == 0
+void sBucketClearAdd(sBucket_pt bucket, poly *p, int *length)
+{
+  poly pr = NULL;
+  int  lr = 0;
+  int i = 0;
+
+  while (bucket->buckets[i].p == NULL)
+  {
+    i++;
+    if (i > bucket->max_bucket) goto done;
+  }
+
+  pr = bucket->buckets[i].p;
+  lr = bucket->buckets[i].length;
+  bucket->buckets[i].p = NULL;
+  bucket->buckets[i].length = 0;
+  i++;
+
+  while (i <= bucket->max_bucket)
+  {
+    if (bucket->buckets[i].p != NULL)
+    {
+      pr = p_Add_q(pr, bucket->buckets[i].p, lr, bucket->buckets[i].length,
+                   bucket->bucket_ring);
+      bucket->buckets[i].p = NULL;
+      bucket->buckets[i].length = 0;
+    }
+    i++;
+  }
+
+  done:
+  *p = pr;
+  *length = lr;
+  bucket->max_bucket = 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Sorts a poly using BucketSort
+//
+
+poly sBucketSortMerge(poly p, ring r)
+{
+#ifdef HAVE_ASSUME
+  int l_in = pLength(p);
+#endif
+
+  if (p == NULL || pNext(p) == NULL) return p;
+
+  sBucket_pt bucket = sBucketCreate(r);
+  poly pn = pNext(p);
+
+  do
+  {
+    pNext(p) = NULL;
+    sBucket_Merge_m(bucket, p);
+    p = pn;
+    if (p == NULL) break;
+    pn = pNext(pn);
+  }
+  while (1);
+
+  int l_dummy;
+  sBucketClearMerge(bucket, &pn, &l_dummy);
+  sBucketDestroy(&bucket);
+
+  p_Test(pn, r);
+#ifdef HAVE_ASSUME
+  assume(l_dummy == pLength(pn));
+  assume(l_in == l_dummy);
+#endif
+  return pn;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Sorts a poly using BucketSort
+//
+
+poly sBucketSortAdd(poly p, ring r)
+{
+#ifdef HAVE_ASSUME
+  int l_in = pLength(p);
+#endif
+
+  if (p == NULL || pNext(p) == NULL) return p;
+
+  sBucket_pt bucket = sBucketCreate(r);
+  poly pn = pNext(p);
+
+  do
+  {
+    pNext(p) = NULL;
+    sBucket_Add_p(bucket, p, 1);
+    p = pn;
+    if (p == NULL) break;
+    pn = pNext(pn);
+  }
+  while (1);
+
+  int l_dummy;
+  sBucketClearAdd(bucket, &pn, &l_dummy);
+  sBucketDestroy(&bucket);
+
+  p_Test(pn, r);
+#ifdef HAVE_ASSUME
+  assume(l_dummy == pLength(pn));
+  assume(l_in >= l_dummy);
+#endif
+  return pn;
+}
Index: kernel/sbuckets.h
===================================================================
--- kernel/sbuckets.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/sbuckets.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,84 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/***************************************************************
+ *  File:    sbuckets.h
+ *  Purpose: declaration of routines for sorting and adding up polys using
+ *           a bucket sort
+ *  Note:    If you need to extract the leading momonial of a bucket,
+ *           use kbuckets, instead.
+ *  Author:  obachman (Olaf Bachmann)
+ *  Created: 9/00
+ *  Version: $Id: sbuckets.h,v 1.1.1.1 2003-10-06 12:16:02 Singular Exp $
+ *******************************************************************/
+#ifndef S_BUCKETS_H
+#define S_BUCKETS_H
+
+#include "structs.h"
+
+//////////////////////////////////////////////////////////////////////////
+// Creation/Destruction of buckets
+//
+sBucket_pt    sBucketCreate(ring r = currRing);
+void          sBucketDestroy(sBucket_pt *bucket);
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Convertion from/to SBpolys
+//
+
+// Converts p into a bucket poly (SBpoly) and destroys p
+// Assumes length <= 0 || pLength(p) == length
+void sBucketInit(sBucket_pt bucket, poly p, int length);
+
+// creates and returns new bucket, initializes it with p
+sBucket_pt  sBucketInit( poly p, int length, ring r = currRing);
+
+// Converts SBpoly into a poly and clears bucket
+// i.e., afterwards SBpoly == 0
+// assumes all monomials in bucket are different
+void sBucketClearMerge(sBucket_pt bucket, poly *p, int *length);
+
+// Converts SBpoly into a poly and clears bucket
+// i.e., afterwards SBpoly == 0
+// bucket may contain equal monials
+void sBucketClearAdd(sBucket_pt bucket, poly *p, int *length);
+
+// Converts SBpoly into a poly and detroys bucket
+inline void sBucketDestroyMerge(sBucket_pt bucket, poly *p, int *length)
+{
+  sBucketClearMerge(bucket, p, length);
+  sBucketDestroy(&bucket);
+}
+
+// Converts SBpoly into a poly and detroys bucket
+inline void sBucketDestroyAdd(sBucket_pt bucket, poly *p, int *length)
+{
+  sBucketClearAdd(bucket, p, length);
+  sBucketDestroy(&bucket);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Merges p into Spoly: assumes Bpoly and p have no common monoms
+///
+void sBucket_Merge_p(sBucket_pt bucket, poly p, int lp);
+// adds poly p to bucket
+void sBucket_Add_p(sBucket_pt bucket, poly p, int lp);
+
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Sorts p with bucektSort: assumes all monomials of p are different
+///
+poly sBucketSortMerge(poly p, ring r);
+
+//////////////////////////////////////////////////////////////////////////
+///
+/// Sorts p with bucektSort: p may have equal monomials
+///
+poly sBucketSortAdd(poly p, ring r);
+
+
+#endif // P_BUCKET_SORT
Index: kernel/sdb.cc
===================================================================
--- kernel/sdb.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/sdb.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,320 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: sdb.cc,v 1.1.1.1 2003-10-06 12:16:02 Singular Exp $ */
+/*
+* ABSTRACT: Singular debugger
+*/
+
+#include <unistd.h>   // for unlink,fork,execlp,getpid
+#include <sys/wait.h> // for wait
+#include "mod2.h"
+#include "tok.h"
+#include "omalloc.h"
+#include "febase.h"
+#include "ipshell.h"
+#include "ipid.h"
+#include "sdb.h"
+
+#ifdef HAVE_SDB
+// We use 8 breakpoints - corresponding to a bit in a char variable in procinfo
+// bit 1..7 force a breakpoint, if lineno==sdb_lines[i-1],
+//                         (for displaying only: file sdb_files[i-1])
+// bit 0 force a breakpoint in every line (used for 'n')
+
+int sdb_lines[]={-1,-1,-1,-1,-1,-1,-1,-1};
+char * sdb_files[6];
+int sdb_flags=0;
+
+int sdb_checkline(char f)
+{
+  int i;
+  char ff=f>>1;
+  for(i=0;i<7;i++)
+  {
+    if((ff & 1) && (yylineno==sdb_lines[i]))
+      return i+1;
+    ff>>=1;
+    if (ff==0) return 0;
+  }
+  return 0;
+}
+
+static char *sdb_find_arg(char *p)
+{
+  p++;
+  while (*p==' ') p++;
+  char *pp=p;
+  while (*pp>' ') pp++;
+  *pp='\0';
+  return p;
+}
+
+void sdb_show_bp()
+{
+  for(int i=0; i<7;i++)
+    if (sdb_lines[i]!= -1)
+      Print("Breakpoint %d: %s::%d\n",i+1,sdb_files[i],sdb_lines[i]);
+}
+
+BOOLEAN sdb_set_breakpoint(const char *pp, int given_lineno)
+{
+  idhdl h=ggetid(pp,TRUE);
+  if ((h==NULL)||(IDTYP(h)!=PROC_CMD))
+  {
+    PrintS(" not found\n");
+    return TRUE;
+  }
+  else
+  {
+    procinfov p=(procinfov)IDDATA(h);
+    #ifdef HAVE_DYNAMIC_LOADING
+    if (p->language!=LANG_SINGULAR)
+    {
+      PrintS("is not a Singular procedure\n");
+      return TRUE;
+    }
+    #endif
+    int lineno;
+    if (given_lineno >0) lineno=given_lineno;
+    else                 lineno=p->data.s.body_lineno;
+    int i;
+    if (given_lineno== -1)
+    {
+      i=p->trace_flag;
+      p->trace_flag &=1;
+      Print("breakpoints in %s deleted(%#x)\n",p->procname,i &255);
+      return FALSE;
+    }
+    i=0;
+    while((i<7) && (sdb_lines[i]!=-1)) i++;
+    if (sdb_lines[i]!= -1)
+    {
+      PrintS("too many breakpoints set, max is 7\n");
+      return TRUE;
+    }
+    sdb_lines[i]=lineno;
+    sdb_files[i]=p->libname;
+    i++;
+    p->trace_flag|=(1<<i);
+    Print("breakpoint %d, at line %d in %s\n",i,lineno,p->procname);
+    return FALSE;
+  }
+}
+
+void sdb_edit(procinfo *pi)
+{
+  char * filename = omStrDup("/tmp/sd000000");
+  sprintf(filename+7,"%d",getpid());
+  FILE *fp=fopen(filename,"w");
+  if (fp==NULL)
+  {
+    Print("cannot open %s\n",filename);
+    omFree(filename);
+    return;
+  }
+  if (pi->language!= LANG_SINGULAR)
+  {
+    Print("cannot edit type %d\n",pi->language);
+    fclose(fp);
+    fp=NULL;
+  }
+  else
+  {
+    char *editor=getenv("EDITOR");
+    if (editor==NULL)
+      editor=getenv("VISUAL");
+    if (editor==NULL)
+      editor="vi";
+    editor=omStrDup(editor);
+
+    if (pi->data.s.body==NULL)
+    {
+      iiGetLibProcBuffer(pi);
+      if (pi->data.s.body==NULL)
+      {
+        PrintS("cannot get the procedure body\n");
+        fclose(fp);
+        unlink(filename);
+        omFree(filename);
+        return;
+      }
+    }
+
+    fwrite(pi->data.s.body,1,strlen(pi->data.s.body),fp);
+    fclose(fp);
+
+    int pid=fork();
+    if (pid!=0)
+    {
+      wait(&pid);
+    }
+    else if(pid==0)
+    {
+      if (strchr(editor,' ')==NULL)
+      {
+        execlp(editor,editor,filename,NULL);
+        Print("cannot exec %s\n",editor);
+      }
+      else
+      {
+        char *p=(char *)omAlloc(strlen(editor)+strlen(filename)+2);
+        sprintf(p,"%s %s",editor,filename);
+        system(p);
+      }
+      exit(0);
+    }
+    else
+    {
+      PrintS("cannot fork\n");
+    }
+
+    fp=fopen(filename,"r");
+    if (fp==NULL)
+    {
+      Print("cannot read from %s\n",filename);
+    }
+    else
+    {
+      fseek(fp,0L,SEEK_END);
+      long len=ftell(fp);
+      fseek(fp,0L,SEEK_SET);
+
+      omFree((ADDRESS)pi->data.s.body);
+      pi->data.s.body=(char *)omAlloc((int)len+1);
+      myfread( pi->data.s.body, len, 1, fp);
+      pi->data.s.body[len]='\0';
+      fclose(fp);
+    }
+  }
+  unlink(filename);
+  omFree(filename);
+}
+
+static char sdb_lastcmd='c';
+
+void sdb(Voice * currentVoice, const char * currLine, int len)
+{
+  int bp=0;
+  if ((len>1)
+  && ((currentVoice->pi->trace_flag & 1)
+    || (bp=sdb_checkline(currentVoice->pi->trace_flag)))
+  )
+  {
+    loop
+    {
+      char gdb[80];
+      char *p=(char *)currLine+len-1;
+      while ((*p<=' ') && (p!=currLine))
+      {
+        p--; len--;
+      }
+      if (p==currLine) return;
+
+      currentVoice->pi->trace_flag&= ~1; // delete flag for "all lines"
+      Print("(%s,%d) >>",currentVoice->filename,yylineno);
+      fwrite(currLine,1,len,stdout);
+      Print("<<\nbreakpoint %d (press ? for list of commands)\n",bp);
+      p=fe_fgets_stdin(">>",gdb,80);
+      while (*p==' ') p++;
+      if (*p >' ')
+      {
+        sdb_lastcmd=*p;
+      }
+      Print("command:%c\n",sdb_lastcmd);
+      switch(sdb_lastcmd)
+      {
+        case '?':
+        case 'h':
+        {
+          PrintS(
+          "b - print backtrace of calling stack\n"
+          "B <proc> [<line>] - define breakpoint\n"
+          "c - continue\n"
+          "d - delete current breakpoint\n"
+          "D - show all breakpoints\n"
+          "e - edit the current procedure (current call will be aborted)\n"
+          "h,? - display this help screen\n"
+          "n - execute current line, break at next line\n"
+          "p <var> - display type and value of the variable <var>\n"
+          "q <flags> - quit debugger, set debugger flags(0,1,2)\n"
+          "Q - quit Singular\n");
+          int i;
+          for(i=0;i<7;i++)
+          {
+            if (sdb_lines[i] != -1)
+              Print("breakpoint %d at line %d in %s\n",
+                i,sdb_lines[i],sdb_files[i]);
+          }
+          break;
+        }
+        case 'd':
+        {
+          Print("delete break point %d\n",bp);
+          currentVoice->pi->trace_flag &= (~Sy_bit(bp));
+          if (bp!=0)
+          {
+            sdb_lines[bp-1]=-1;
+          }
+          break;
+        }
+        case 'D':
+          sdb_show_bp();
+          break;
+        case 'n':
+          currentVoice->pi->trace_flag|= 1;
+          return;
+        case 'e':
+        {
+          sdb_edit(currentVoice->pi);
+          sdb_flags=2;
+          return;
+        }
+        case 'p':
+        {
+          p=sdb_find_arg(p);
+          Print("variable `%s`",p);
+          idhdl h=ggetid(p,TRUE);
+          if (h==NULL)
+            PrintS(" not found\n");
+          else
+          {
+            sleftv tmp;
+            memset(&tmp,0,sizeof(tmp));
+            tmp.rtyp=IDHDL;
+            tmp.data=h;
+            Print("(type %s):\n",Tok2Cmdname(tmp.Typ()));
+            tmp.Print();
+          }
+          break;
+        }
+        case 'b':
+          VoiceBackTrack();
+          break;
+        case 'B':
+        {
+          p=sdb_find_arg(p);
+          Print("procedure `%s` ",p);
+          sdb_set_breakpoint(p);
+          break;
+        }
+        case 'q':
+        {
+          p=sdb_find_arg(p);
+          if (*p!='\0')
+          {
+            sdb_flags=atoi(p);
+            Print("new sdb_flags:%d\n",sdb_flags);
+          }
+          return;
+        }
+        case 'Q':
+          m2_end(999);
+        case 'c':
+        default:
+          return;
+      }
+    }
+  }
+}
+#endif
Index: kernel/sdb.h
===================================================================
--- kernel/sdb.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/sdb.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,27 @@
+#ifndef SDB_H
+#define SDB_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: sdb.h,v 1.1.1.1 2003-10-06 12:16:03 Singular Exp $ */
+/*
+* ABSTRACT: Singular debugger
+*/
+
+#define HAVE_SDB
+
+#ifdef HAVE_SDB
+#include "febase.h"
+#include "structs.h"
+
+extern int    sdb_lines[];
+extern char * sdb_files[];
+extern int    sdb_flags;
+
+void sdb_edit(procinfo *pi);
+void sdb_show_bp();
+BOOLEAN sdb_set_breakpoint(const char *p, int lineno=0);
+void sdb(Voice * currentVoice, const char * currLine, int len);
+#endif
+#endif
+
Index: kernel/semic.cc
===================================================================
--- kernel/semic.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/semic.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,485 @@
+// ----------------------------------------------------------------------------
+//  semic.cc
+//  begin of file
+//  Stephan Endrass, endrass@mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#define SEMIC_CC
+
+#include"mod2.h"
+
+#ifdef HAVE_SPECTRUM
+
+#ifdef  SEMIC_PRINT
+#ifndef SEMIC_IOSTREAM
+#include<stdio.h>
+#else
+#include<iostream.h>
+#endif
+#endif
+
+#include<string.h>
+#ifndef ix86_Win
+//#include<values.h>
+#endif
+
+#include"intvec.h"
+#include"GMPrat.h"
+#include"semic.h"
+
+// ----------------------------------------------------------------------------
+//  Delete the memory of a spectrum
+// ----------------------------------------------------------------------------
+
+inline void spectrum::copy_delete( void )
+{
+    if( s != (Rational*)NULL && n > 0 ) delete [] s;
+    if( w != (int*)NULL      && n > 0 ) delete [] w;
+    copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  Allocate memory for a spectrum of  k  numbers
+// ----------------------------------------------------------------------------
+
+void spectrum::copy_new( int k )
+{
+    if( k > 0 )
+    {
+        s = new Rational[k];
+        w = new int[k];
+
+        #ifndef NDEBUG
+        if( s == (Rational*)NULL || w == (int*)NULL )
+        {
+            #ifdef SEMIC_PRINT
+            #ifdef SEMIC_IOSTREAM
+                cerr << "spectrum::copy_new(" << k << ")" << endl;
+                cerr << "    returned ZERO!!!" << endl;
+                cerr << "    exit..." << endl;
+            #else
+                fprintf( stderr,"spectrum::copy_new( %d )\n",k );
+                fprintf( stderr,"    returned ZERO!!!\n" );
+                fprintf( stderr,"    exit...\n" );
+            #endif
+            #endif
+        }
+        #endif
+    }
+    else if( k == 0 )
+    {
+        s = (Rational*)NULL;
+        w = (int*)NULL;
+    }
+    else if( k < 0 )
+    {
+        #ifdef SEMIC_PRINT
+        #ifdef SEMIC_IOSTREAM
+                cerr << "spectrum::copy_new(" << k << ")";
+                cerr << ": k < 0 ..." << endl;
+        #else
+                fprintf( stderr,"spectrum::copy_new( %d )",k );
+                fprintf( stderr,": k < 0 ...\n" );
+        #endif
+        #endif
+
+        exit( 1 );
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  Copy constructor for  spectrum
+// ----------------------------------------------------------------------------
+
+spectrum::spectrum( const spectrum &spec )
+{
+    copy_deep( spec );
+}
+
+// ----------------------------------------------------------------------------
+//  Destructor for  spectrum
+// ----------------------------------------------------------------------------
+
+spectrum::~spectrum( )
+{
+    copy_delete( );
+}
+
+
+// ----------------------------------------------------------------------------
+//  operator  =  for  spectrum
+// ----------------------------------------------------------------------------
+
+spectrum spectrum::operator = ( const spectrum &spec )
+{
+    copy_delete( );
+    copy_deep( spec );
+
+    return *this;
+}
+
+// ----------------------------------------------------------------------------
+//  add the two spectra  s1  and  s2  and return their sum
+// ----------------------------------------------------------------------------
+
+spectrum  operator + ( const spectrum &s1,const spectrum &s2 )
+{
+    int i1=0, i2=0, i3=0;
+
+    spectrum result;
+
+    do
+    {
+        if( i1 >= s1.n )
+        {
+            i2++;
+        }
+        else if( i2 >= s2.n )
+        {
+            i1++;
+        }
+        else if( s1.s[i1] < s2.s[i2] )
+        {
+            i1++;
+        }
+        else if( s1.s[i1] == s2.s[i2] )
+        {
+            i1++;
+            i2++;
+        }
+        else
+        {
+            i2++;
+        }
+        i3++;
+    }
+    while( i1 < s1.n || i2 < s2.n );
+
+    result.copy_new( i3 );
+    result.n = i3;
+
+    i1 = i2 = i3 = 0;
+
+    do
+    {
+        if( i1 >= s1.n )
+        {
+            result.s[i3] = s2.s[i2];
+            result.w[i3] = s2.w[i2];
+            i2++;
+        }
+        else if( i2 >= s2.n )
+        {
+            result.s[i3] = s1.s[i1];
+            result.w[i3] = s1.w[i1];
+            i1++;
+        }
+        else if( s1.s[i1] < s2.s[i2] )
+        {
+            result.s[i3] = s1.s[i1];
+            result.w[i3] = s1.w[i1];
+            i1++;
+          }
+        else if( s1.s[i1] == s2.s[i2] )
+        {
+            result.s[i3] = s1.s[i1];
+            result.w[i3] = s1.w[i1] + s2.w[i2];
+            i1++;
+            i2++;
+        }
+        else
+        {
+            result.s[i3] = s2.s[i2];
+            result.w[i3] = s2.w[i2];
+            i2++;
+        }
+        i3++;
+    }
+    while( i1 < s1.n || i2 < s2.n );
+
+    result.mu = s1.mu + s2.mu;
+    result.pg = s1.pg + s2.pg;
+
+    return  result;
+}
+
+// ----------------------------------------------------------------------------
+//  multiply the multiplicities of the spectrum numbers of  a  with  m
+// ----------------------------------------------------------------------------
+
+spectrum operator * ( int k,const spectrum &spec )
+{
+    if( k == 0 )
+    {
+        spectrum result;
+
+        return  result;
+    }
+    else
+    {
+        spectrum result( spec );
+
+        result.mu *= k;
+        result.pg *= k;
+
+        for( int i=0; i<result.n; i++ )
+        {
+            result.w[i] *= k;
+        }
+
+        return  result;
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  Print a  spectrum
+// ----------------------------------------------------------------------------
+
+#ifdef SEMIC_PRINT
+
+ostream & operator << ( ostream &s,const spectrum &spec )
+{
+    for( int i=0; i<spec.n; i++ )
+    {
+        if( i>0 )
+        {
+            #ifdef SEMIC_STDOUT
+                s << "+";
+            #else
+                fprintf( stdout,"+" );
+            #endif
+        }
+
+        #ifdef SEMIC_STDOUT
+            s << spec.w[i] << "*t^";
+        #else
+            fprintf( stdout,"%d*t^",spec.w[i] );
+        #endif
+
+        s << spec.s[i];
+    }
+
+    return s;
+}
+#endif
+
+// ----------------------------------------------------------------------------
+//  Add a subspectrum with multiplicity  k  (faster than '+')
+// ----------------------------------------------------------------------------
+
+int    spectrum::add_subspectrum( spectrum &a,int k )
+{
+    int i,j;
+    for( i=0, j=0; i<n; i++ )
+    {
+        if( s[i] == a.s[j] )
+        {
+            w[i] += k*a.w[j];
+            j++;
+        }
+    }
+
+    return ( j == a.n ? TRUE : FALSE );
+}
+
+// ----------------------------------------------------------------------------
+//  set  *alpha  to the next spectrum number strictly bigger than  *alpha
+//  returns: TRUE, if such a spectrum number exists
+//           FALSE otherwise
+// ----------------------------------------------------------------------------
+
+int    spectrum::next_number( Rational *alpha )
+{
+    int i=0;
+
+    while( i < n && *alpha >= s[i]  )
+    {
+        i++;
+    }
+
+    if( i < n )
+    {
+        *alpha = s[i];
+        return TRUE;
+    }
+    else
+    {
+        return FALSE;
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  find the next interval on the real line of same length as
+//  [*alpha1,*alpha2]  having a spectrum number as interval border
+// ----------------------------------------------------------------------------
+
+int     spectrum::next_interval( Rational *alpha1,Rational *alpha2 )
+{
+    Rational zero( 0,1 );
+    Rational a1 = *alpha1;
+    Rational a2 = *alpha2;
+    Rational d  = *alpha2 - *alpha1;
+
+    int    e1 = this->next_number( &a1 );
+    int    e2 = this->next_number( &a2 );
+
+    if( e1 || e2 )
+    {
+        Rational d1 = a1 - *alpha1;
+        Rational d2 = a2 - *alpha2;
+
+        if( d1 < d2 || d2 == zero )
+        {
+            *alpha1 = a1;
+            *alpha2 = a1 + d;
+        }
+        else
+        {
+            *alpha1 = a2 - d;
+            *alpha2 = a2;
+        }
+        return  TRUE;
+    }
+    else
+    {
+        return  FALSE;
+    }
+}
+
+// ----------------------------------------------------------------------------
+//  compute the numver of spectrum numbers in the inverval  [*alpha1,*alpha2]
+// ----------------------------------------------------------------------------
+
+int     spectrum::numbers_in_interval( Rational &alpha1,
+                Rational &alpha2,interval_status status )
+{
+    int count = 0;
+
+    for( int i=0; i<n; i++ )
+    {
+        if( ( ( status == OPEN   || status == LEFTOPEN  ) &&
+              s[i] >  alpha1 ) ||
+            ( ( status == CLOSED || status == RIGHTOPEN ) &&
+              s[i] >= alpha1 ) )
+        {
+              if( ( ( status == OPEN   || status == RIGHTOPEN  ) &&
+                  s[i] <  alpha2 ) ||
+                ( ( status == CLOSED || status == LEFTOPEN ) &&
+                  s[i] <= alpha2 ) )
+            {
+                count += w[i];
+            }
+            else
+            {
+                break;
+            }
+        }
+    }
+
+    return count;
+}
+
+// ----------------------------------------------------------------------------
+//  find the maximal integer  k  such that  k*t is semicontinous
+//  for the spectrum
+// ----------------------------------------------------------------------------
+
+int     spectrum::mult_spectrum( spectrum &t )
+{
+    spectrum u = *this + t;
+
+    Rational alpha1 = -2;
+    Rational alpha2 = -1;
+
+    int      mult=INT_MAX,nthis,nt;
+
+    while( u.next_interval( &alpha1,&alpha2 ) )
+    {
+        nt    = t.numbers_in_interval( alpha1,alpha2,LEFTOPEN );
+        nthis = this->numbers_in_interval( alpha1,alpha2,LEFTOPEN );
+
+        if( nt != 0 )
+        {
+            mult = (nthis/nt < mult ? nthis/nt: mult );
+        }
+
+    }
+
+    return  mult;
+}
+
+// ----------------------------------------------------------------------------
+//  find the maximal integer  k  such that  k*t is semicontinous
+//  for the spectrum (in the homogeneous sense)
+// ----------------------------------------------------------------------------
+
+int     spectrum::mult_spectrumh( spectrum &t )
+{
+    spectrum u = *this + t;
+
+    Rational alpha1 = -2;
+    Rational alpha2 = -1;
+
+    int      mult=INT_MAX,nthis,nt;
+
+    while( u.next_interval( &alpha1,&alpha2 ) )
+    {
+        nt    = t.numbers_in_interval( alpha1,alpha2,LEFTOPEN );
+        nthis = this->numbers_in_interval( alpha1,alpha2,LEFTOPEN );
+
+        if( nt != 0 )
+        {
+            mult = (nthis/nt < mult ? nthis/nt: mult );
+        }
+
+        nt    = t.numbers_in_interval( alpha1,alpha2,OPEN );
+        nthis = this->numbers_in_interval( alpha1,alpha2,OPEN );
+
+        if( nt != 0 )
+        {
+            mult = (nthis/nt < mult ? nthis/nt: mult );
+        }
+    }
+
+    return  mult;
+}
+
+// ----------------------------------------------------------------------------
+//  Set the Milnor number
+// ----------------------------------------------------------------------------
+
+/*
+int spectrum::set_milnor( void )
+{
+   mu = 0;
+
+   for( int i=0; i<n; i++ )
+   {
+      mu += w[i];
+   }
+
+   return  mu;
+}
+
+// ----------------------------------------------------------------------------
+//  Set the geometrical genus
+// ----------------------------------------------------------------------------
+
+int spectrum::set_geometric_genus( void )
+{
+   pg = 0;
+
+   for( int i=0; i<n && s[i]<=1; i++ )
+   {
+      pg += w[i];
+   }
+   return  pg;
+}
+*/
+
+#endif /* HAVE_SPECTRUM */
+// ----------------------------------------------------------------------------
+//  semic.cc
+//  end of file
+// ----------------------------------------------------------------------------
Index: kernel/semic.h
===================================================================
--- kernel/semic.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/semic.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,147 @@
+// ----------------------------------------------------------------------------
+//  semic.h
+//  begin of file
+//  Stephan Endrass, endrass@mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+//  here we define a class  spectrum  to test semicontinuity
+// ----------------------------------------------------------------------------
+
+#ifndef SEMIC_H
+#define SEMIC_H
+
+#include "GMPrat.h"
+
+typedef enum
+{
+    OPEN,
+    LEFTOPEN,
+    RIGHTOPEN,
+    CLOSED
+
+} interval_status;
+
+typedef enum
+{
+    semicOK,
+    semicMulNegative,
+
+    semicListTooShort,
+    semicListTooLong,
+
+    semicListFirstElementWrongType,
+    semicListSecondElementWrongType,
+    semicListThirdElementWrongType,
+    semicListFourthElementWrongType,
+    semicListFifthElementWrongType,
+    semicListSixthElementWrongType,
+
+    semicListNNegative,
+    semicListWrongNumberOfNumerators,
+    semicListWrongNumberOfDenominators,
+    semicListWrongNumberOfMultiplicities,
+
+    semicListMuNegative,
+    semicListPgNegative,
+    semicListNumNegative,
+    semicListDenNegative,
+    semicListMulNegative,
+
+    semicListNotSymmetric,
+    semicListNotMonotonous,
+
+    semicListMilnorWrong,
+    semicListPGWrong
+
+} semicState;
+
+class spectrum
+{
+public:
+
+    int         mu;      // milnor number
+    int         pg;      // geometrical genus
+    int         n;       // # of spectrum numbers
+    Rational    *s;      // spectrum numbers
+    int         *w;      // multiplicities
+
+    spectrum( );
+    spectrum( const spectrum& );
+    spectrum( lists );
+
+    ~spectrum( );
+
+    spectrum operator = ( const spectrum& );
+    spectrum operator = ( lists );
+
+    friend spectrum   operator + ( const spectrum&,const spectrum& );
+    friend spectrum   operator * ( int,const spectrum& );
+
+    #ifdef SEMIC_PRINT
+    friend ostream &  operator << ( ostream&,const spectrum& );
+    #endif SEMIC_PRINT
+
+    void    copy_new    ( int );
+    void    copy_delete ( void );
+    void    copy_zero   ( void );
+
+    void    copy_shallow( spectrum& );
+    void    copy_deep   ( const spectrum& );
+    void    copy_deep   ( lists );
+
+    lists   thelist     ( void );
+
+    int     add_subspectrum    ( spectrum&,int );
+    int     next_number        ( Rational* );
+    int     next_interval      ( Rational*,Rational* );
+    int     numbers_in_interval( Rational&,Rational&,interval_status );
+    int     mult_spectrum      ( spectrum& );
+    int     mult_spectrumh     ( spectrum& );
+
+    //    int     set_milnor         ( void );
+    //   int     set_geometric_genus( void );
+};
+
+
+// ----------------------------------------------------------------------------
+//  Initialize with zero
+// ----------------------------------------------------------------------------
+
+inline void spectrum::copy_zero( void )
+{
+    mu = 0;
+    pg = 0;
+    n  = 0;
+    s  = (Rational*)NULL;
+    w  = (int*)NULL;
+}
+
+// ----------------------------------------------------------------------------
+//  Initialize shallow from another spectrum
+// ----------------------------------------------------------------------------
+
+inline void spectrum::copy_shallow( spectrum &spec )
+{
+    mu = spec.mu;
+    pg = spec.pg;
+    n  = spec.n;
+    s  = spec.s;
+    w  = spec.w;
+}
+
+// ----------------------------------------------------------------------------
+//  Zero constructor
+// ----------------------------------------------------------------------------
+
+inline spectrum::spectrum( )
+{
+    copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  semic.h
+//  end of file
+// ----------------------------------------------------------------------------
+#endif
Index: kernel/shortfl.cc
===================================================================
--- kernel/shortfl.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/shortfl.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,449 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: shortfl.cc,v 1.1.1.1 2003-10-06 12:16:03 Singular Exp $ */
+
+/*
+* ABSTRACT:
+*/
+
+#include <string.h>
+#include "mod2.h"
+#include <mylimits.h>
+#include "structs.h"
+#include "febase.h"
+#include "numbers.h"
+#include "longrat.h"
+#include "mpr_complex.h"
+#include "ring.h"
+#include "shortfl.h"
+
+static float nrEps = 1.0e-3;
+union nf
+{
+  float _f;
+  number _n;
+  nf(float f) {_f = f;}
+  nf(number n) {_n = n;}
+  float F() const {return _f;}
+  number N() const {return _n;}
+};
+
+float nrFloat(number n)
+{
+  return nf(n).F();
+}
+
+BOOLEAN nrGreaterZero (number k)
+{
+  return nf(k).F() >= 0.0;
+}
+
+number nrMult (number a,number b)
+{
+  return nf(nf(a).F() * nf(b).F()).N();
+}
+
+/*2
+* create a number from int
+*/
+number nrInit (int i)
+{
+  float r = (float)i;
+  return nf(nf(r).F()).N();
+}
+
+/*2
+* convert a number to int
+*/
+int nrInt(number &n)
+{
+  int i;
+  float r = nf(n).F();
+  if (((float)INT_MIN <= r) || ((float)MAX_INT_VAL >= r))
+    i = (int)r;
+  else
+    i = 0;
+  return i;
+}
+
+number nrAdd (number a, number b)
+{
+  float x = nf(a).F();
+  float y = nf(b).F();
+  float r = x + y;
+  if (x > 0.0)
+  {
+    if (y < 0.0)
+    {
+      x = r / (x - y);
+      if (x < 0.0)
+        x = -x;
+      if (x < nrEps)
+        r = 0.0;
+    }
+  }
+  else
+  {
+    if (y > 0.0)
+    {
+      x = r / (y - x);
+      if (x < 0.0)
+        x = -x;
+      if (x < nrEps)
+        r = 0.0;
+    }
+  }
+  return nf(r).N();
+}
+
+number nrSub (number a, number b)
+{
+  float x = nf(a).F();
+  float y = nf(b).F();
+  float r = x - y;
+  if (x > 0.0)
+  {
+    if (y > 0.0)
+    {
+      x = r / (x + y);
+      if (x < 0.0)
+        x = -x;
+      if (x < nrEps)
+        r = 0.0;
+    }
+  }
+  else
+  {
+    if (y < 0.0)
+    {
+      x = r / (x + y);
+      if (x < 0.0)
+        x = -x;
+      if (x < nrEps)
+        r = 0.0;
+    }
+  }
+  return nf(r).N();
+}
+
+BOOLEAN nrIsZero (number  a)
+{
+  return (0.0 == nf(a).F());
+}
+
+BOOLEAN nrIsOne (number a)
+{
+  float aa=nf(a).F()-1.0;
+  if (aa<0.0) aa=-aa;
+  return (aa<nrEps);
+}
+
+BOOLEAN nrIsMOne (number a)
+{
+  float aa=nf(a).F()+1.0;
+  if (aa<0.0) aa=-aa;
+  return (aa<nrEps);
+}
+
+number nrDiv (number a,number b)
+{
+  float n = nf(b).F();
+  if (n == 0.0)
+  {
+    WerrorS("a/0");
+    return nf((float)0.0).N();
+  }
+  else
+    return nf(nf(a).F() / n).N();
+}
+
+number  nrInvers (number c)
+{
+  float n = nf(c).F();
+  if (n == 0.0)
+  {
+    WerrorS("1/0");
+    return nf((float)0.0).N();
+  }
+  return nf(1.0 / n).N();
+}
+
+number nrNeg (number c)
+{
+  return nf(-nf(c).F()).N();
+}
+
+BOOLEAN nrGreater (number a,number b)
+{
+  return nf(a).F() > nf(b).F();
+}
+
+BOOLEAN nrEqual (number a,number b)
+{
+  number x = nrSub(a,b);
+  return nf(x).F() == nf((float)0.0).F();
+}
+
+void nrWrite (number &a)
+{
+  StringAppend("%9.3e", nf(a).F());
+}
+
+void nrPower (number a, int i, number * result)
+{
+  if (i==0)
+  {
+    *result = nf(nf(1.0).F()).N();
+    return;
+  }
+  if (i==1)
+  {
+    *result = nf(nf(a).F()).N();
+    return;
+  }
+  nrPower(a,i-1,result);
+  *result = nf(nf(a).F() * nf(*result).F()).N();
+}
+
+char* nrEatr(char *s, float *r)
+{
+  int i;
+
+  if    (*s >= '0' && *s <= '9')
+  {
+    *r = 0.0;
+    do
+    {
+      *r *= 10.0;
+      i = *s++ - '0';
+      *r += (float)i;
+    }
+    while (*s >= '0' && *s <= '9');
+  }
+  else *r = 1.0;
+  return s;
+}
+
+char * nrRead (char *s, number *a)
+{
+  char *t;
+  float z1,z2;
+  float n=1.0;
+
+  s = nrEatr(s, &z1);
+  if (*s == '/')
+  {
+    s++;
+    s = nrEatr(s, &z2);
+    z1 /= z2;
+  }
+  else if (*s =='.')
+  {
+    s++;
+    t = s;
+    while (*t >= '0' && *t <= '9')
+    {
+      t++;
+      n *= 10.0;
+    }
+    s = nrEatr(s, &z2);
+    z1 = (z1*n + z2) / n;
+    if (*s=='e')
+    {
+      int e=0; /* exponent */
+      int si=1;/* sign of exponent */
+      s++;
+      if (*s=='+') s++;
+      else if (*s=='-') {s++; si=-1; }
+      while (*s >= '0' && *s <= '9')
+      {
+        e=e*10+(*s)-'0';
+        s++;
+      }
+      if (si==1)
+      {
+        while (e>0) {z1*=10.0; e--; }
+      }
+      else
+      {
+        while (e>0) {z1/=10.0; e--; }
+      }
+    }
+  }
+  *a = nf(z1).N();
+  return s;
+}
+
+/*2
+* the last used charcteristic
+*/
+int nrGetChar()
+{
+  return 0;
+}
+
+#ifdef LDEBUG
+/*2
+* test valid numbers: not implemented yet
+*/
+BOOLEAN nrDBTest(number a, char *f, int l)
+{
+  return TRUE;
+}
+#endif
+
+/* in longrat.h
+typedef MP_INT lint;
+#define SR_INT    1
+#define mpz_size1(A) (ABS((A)->_mp_size))
+*/
+#define SR_HDL(A) ((long)(A))
+#define mpz_isNeg(A) ((A)->_mp_size<0)
+#define mpz_limb_size(A) ((A)->_mp_size)
+#define mpz_limb_d(A) ((A)->_mp_d)
+#define MPZ_DIV(A,B,C) mpz_tdiv_q((A),(B),(C))
+#define IS_INT(A) ((A)->s==3)
+#define IS_IMM(A) (SR_HDL(A)&SR_INT)
+#define GET_NOM(A) &((A)->z)
+#define GET_DENOM(A) &((A)->n)
+#define MPZ_INIT mpz_init
+#define MPZ_CLEAR mpz_clear
+
+static number nrMapQ(number from)
+{
+  lint h,*g,*z,*n;
+  int i,j,t,s;
+  float ba,rr,rn,y;
+
+  if (IS_IMM(from))
+    return nf((float)nlInt(from)).N();
+  z=GET_NOM(from);
+  s=0X10000;
+  ba=(float)s;
+  ba*=ba;
+  rr=0.0;
+  i=mpz_size1(z);
+  if(IS_INT(from))
+  {
+    if(i>4)
+    {
+      WerrorS("float overflow");
+      return nf(rr).N();
+    }
+    i--;
+    rr=(float)mpz_limb_d(z)[i];
+    while(i>0)
+    {
+      i--;
+      y=(float)mpz_limb_d(z)[i];
+      rr=rr*ba+y;
+    }
+    if(mpz_isNeg(z))
+      rr=-rr;
+    return nf(rr).N();
+  }
+  n=GET_DENOM(from);
+  j=s=mpz_limb_size(n);
+  if(j>i)
+  {
+    g=n; n=z; z=g;
+    t=j; j=i; i=t;
+  }
+  t=i-j;
+  if(t>4)
+  {
+    if(j==s)
+      WerrorS("float overflow");
+    return nf(rr).N();
+  }
+  if(t>1)
+  {
+    g=&h;
+    MPZ_INIT(g);
+    MPZ_DIV(g,z,n);
+    t=mpz_size1(g);
+    if(t>4)
+    {
+      MPZ_CLEAR(g);
+      if(j==s)
+        WerrorS("float overflow");
+      return nf(rr).N();
+    }
+    t--;
+    rr=(float)mpz_limb_d(g)[t];
+    while(t)
+    {
+      t--;
+      y=(float)mpz_limb_d(g)[t];
+      rr=rr*ba+y;
+    }
+    MPZ_CLEAR(g);
+    if(j!=s)
+      rr=1.0/rr;
+    if(mpz_isNeg(z))
+      rr=-rr;
+    return nf(rr).N();
+  }
+  rn=(float)mpz_limb_d(n)[j-1];
+  rr=(float)mpz_limb_d(z)[i-1];
+  if(j>1)
+  {
+    rn=rn*ba+(float)mpz_limb_d(n)[j-2];
+    rr=rr*ba+(float)mpz_limb_d(z)[i-2];
+    i--;
+  }
+  if(t!=0)
+    rr=rr*ba+(float)mpz_limb_d(z)[i-2];
+  if(j==s)
+    rr=rr/rn;
+  else
+    rr=rn/rr;
+  if(mpz_isNeg(z))
+    rr=-rr;
+  return nf(rr).N();
+}
+
+static number nrMapP(number from)
+{
+  int i = (int)from;
+  float r = (float)i;
+  return nf(r).N();
+}
+
+static number nrMapLongR(number from)
+{
+  float t =(float)mpf_get_d((mpf_srcptr)from);
+  return nf(t).N();
+}
+static number nrMapC(number from)
+{
+  gmp_float h = ((gmp_complex*)from)->real();
+  float t =(float)mpf_get_d((mpf_srcptr)&h);
+  return nf(t).N();
+}
+
+nMapFunc nrSetMap(ring src, ring dst)
+{
+  if (rField_is_Q(src))
+  {
+    return nrMapQ;
+  }
+  if (rField_is_long_R(src))
+  {
+    return nrMapLongR;
+  }
+  if (rField_is_R(src))
+  {
+    return ndCopy;
+  }
+  if(rField_is_Zp(src))
+  {
+    return nrMapP;
+  }
+  if (rField_is_long_C(src))
+  {
+    return nrMapC;
+  }
+  return NULL;
+}
Index: kernel/shortfl.h
===================================================================
--- kernel/shortfl.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/shortfl.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,38 @@
+#ifndef SHORTFL_H
+#define SHORTFL_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT
+*/
+/* $Id: shortfl.h,v 1.1.1.1 2003-10-06 12:16:03 Singular Exp $ */
+#include "structs.h"
+
+BOOLEAN nrGreaterZero (number k);
+number  nrMult        (number a, number b);
+number  nrInit        (int i);
+int     nrInt         (number &n);
+number  nrAdd         (number a, number b);
+number  nrSub         (number a, number b);
+void    nrPower       (number a, int i, number * result);
+BOOLEAN nrIsZero      (number a);
+BOOLEAN nrIsOne       (number a);
+BOOLEAN nrIsMOne      (number a);
+number  nrDiv         (number a, number b);
+number  nrNeg         (number c);
+number  nrInvers      (number c);
+BOOLEAN nrGreater     (number a, number b);
+BOOLEAN nrEqual       (number a, number b);
+void    nrWrite       (number &a);
+char *  nrRead        (char *s, number *a);
+int     nrGetChar();
+#ifdef LDEBUG
+BOOLEAN nrDBTest(number a, char *f, int l);
+#endif
+
+nMapFunc nrSetMap(ring src, ring dst);
+
+float   nrFloat(number n);
+#endif
+
Index: kernel/si_gmp.h
===================================================================
--- kernel/si_gmp.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/si_gmp.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,16 @@
+/* $Id: si_gmp.h,v 1.1.1.1 2003-10-06 12:16:03 Singular Exp $ */
+
+#ifndef INCL_CF_GMP_H
+#define INCL_CF_GMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#undef __cplusplus
+#include <gmp.h>
+#define __cplusplus
+}
+#else
+#include <gmp.h>
+#endif
+
+#endif /* ! INCL_CF_GMP_H */
Index: kernel/silink.h
===================================================================
--- kernel/silink.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/silink.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,103 @@
+#ifndef SILINK_H
+#define SILINK_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: silink.h,v 1.1.1.1 2003-10-06 12:16:03 Singular Exp $ */
+/*
+* ABSTRACT: general interface to links
+*/
+
+#include "structs.h"
+
+// extension links:
+typedef BOOLEAN    (*slOpenProc)(si_link l, short flag);
+typedef BOOLEAN    (*slWriteProc)(si_link l, leftv lv);
+typedef BOOLEAN    (*slCloseProc)(si_link l);
+typedef BOOLEAN    (*slKillProc)(si_link l);
+typedef leftv      (*slReadProc)(si_link l);
+typedef leftv      (*slRead2Proc)(si_link l, leftv a);
+typedef BOOLEAN    (*slDumpProc)(si_link l);
+typedef BOOLEAN    (*slGetDumpProc)(si_link l);
+typedef char*      (*slStatusProc)(si_link l, char *request);
+
+struct s_si_link_extension
+{
+  si_link_extension next;
+  slOpenProc       Open;
+  slCloseProc      Close;
+  slKillProc       Kill;
+  slReadProc       Read;
+  slRead2Proc      Read2;
+  slWriteProc      Write;
+  slDumpProc       Dump;
+  slGetDumpProc    GetDump;
+  slStatusProc     Status;
+  char             *type;
+};
+
+struct sip_link
+{
+  si_link_extension m; // methods
+  char *mode;
+  char *name;          // used for filename and/or further specs
+  void *data;          // the link itself
+  BITSET flags;        // 0=close open = 1: read = 2: write = 3
+  short ref;           // reference counter
+};
+
+// flags:
+#define SI_LINK_CLOSE   0
+#define SI_LINK_OPEN    1
+#define SI_LINK_READ    2
+#define SI_LINK_WRITE   4
+
+// tests:
+#define SI_LINK_CLOSE_P(l)  (!(l)->flags)
+#define SI_LINK_OPEN_P(l)   ((l)->flags & SI_LINK_OPEN)
+#define SI_LINK_W_OPEN_P(l) ((l)->flags &  SI_LINK_WRITE)
+#define SI_LINK_R_OPEN_P(l) ((l)->flags &  SI_LINK_READ)
+#define SI_LINK_RW_OPEN_P(l) (SI_LINK_W_OPEN_P(l) && SI_LINK_R_OPEN_P(l))
+
+#define SI_LINK_SET_CLOSE_P(l)  ((l)->flags = SI_LINK_CLOSE)
+#define SI_LINK_SET_OPEN_P(l, flag)   ((l)->flags = (l)->flags |SI_LINK_OPEN |flag)
+#define SI_LINK_SET_W_OPEN_P(l) ((l)->flags = (l)->flags | SI_LINK_OPEN | SI_LINK_WRITE)
+#define SI_LINK_SET_R_OPEN_P(l) ((l)->flags = (l)->flags | SI_LINK_OPEN | SI_LINK_READ)
+#define SI_LINK_SET_RW_OPEN_P(l) ((l)->flags = (l)->flags | SI_LINK_OPEN | SI_LINK_READ | SI_LINK_WRITE)
+
+BOOLEAN slOpen(si_link l, short flag);
+BOOLEAN slClose(si_link l);
+leftv   slRead(si_link l,leftv a=NULL);
+BOOLEAN slWrite(si_link l, leftv v);
+BOOLEAN slDump(si_link l);
+BOOLEAN slGetDump(si_link l);
+char* slStatus(si_link l, char *request);
+char* slStatusAscii(si_link l, char* request);
+BOOLEAN slInit(si_link l, char *str);
+void slKill(si_link l);
+void slCleanUp(si_link l);
+void slStandardInit();
+inline si_link slCopy(si_link l)
+{
+  l->ref++;
+  return l;
+}
+
+#include "omalloc.h"
+inline char* slString(si_link l)
+{
+  if (l->name != NULL)
+  {
+    return omStrDup(l->name);
+  }
+  else
+  {
+    return omStrDup("");
+  }
+}
+
+extern omBin s_si_link_extension_bin;
+extern omBin sip_link_bin;
+extern omBin ip_link_bin;
+
+#endif // SILINK_H
Index: kernel/sing_dbm.h
===================================================================
--- kernel/sing_dbm.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/sing_dbm.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,14 @@
+#ifndef SING_DBM_H
+#define SING_DBM_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: sing_dbm.h,v 1.1.1.1 2003-10-06 12:16:03 Singular Exp $ */
+/*
+* ABSTRACT: interface to DBM links
+*/
+
+#include "structs.h"
+
+si_link_extension slInitDBMExtension(si_link_extension s);
+#endif
Index: kernel/sing_dld.cc
===================================================================
--- kernel/sing_dld.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/sing_dld.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,119 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/* $Id: sing_dld.cc,v 1.1.1.1 2003-10-06 12:16:03 Singular Exp $ */
+
+/*
+* ABSTRACT: interface to dynamic loading
+*/
+
+#include "mod2.h"
+#include "febase.h"
+#include "structs.h"
+#include "ipshell.h"
+
+
+#ifdef HAVE_DLD
+#ifdef linux
+  #ifdef __ELF__
+  #include <dlfcn.h>
+  #else
+  #include <dld.h>
+  #endif
+#elif defined(hpux)
+#include <dl.h>
+#endif
+
+#ifdef linux
+#ifndef __ELF__
+static int dlInitError=0;
+void dlInit(const char *thisfile)
+{
+  int i=dld_init (thisfile);
+  if (i!=0)
+  {
+    //Print("dld_int:%d, errno:%d\n",i,dld_errno);
+    i=dld_init (dld_find_executable(thisfile));
+    //Print("dld_int(dld_find_executable):%d, errno:%d\n",i,dld_errno);
+    dlInitError=i;
+  }
+}
+#endif
+#endif
+
+BOOLEAN dlLoad(const char * fn, const char *pn)
+{
+  typedef void (*PROC)(void);
+  PROC p1;
+  #ifdef linux
+  #ifdef __ELF__
+  /*======================linux elf dl============================*/
+  void *h=dlopen(fn,RTD_GLOBAL|RTD_NOW);
+  if (h!=NULL)
+  {
+    p1=(PROC)dlsym(h,pn);
+    char *s;
+    if((s=dlerror())==NULL)
+    {
+      p1();
+      return FALSE;
+    }
+    else
+    {
+      Werror("cannot find %s in %s(%s)",pn,fn,s);
+      dlclose(h);
+    }
+  }
+  else
+  {
+    Werror("cannot link %s (%s)",fn,dlerror());
+  }
+  #else
+  /*======================linux dld============================*/
+  if (dlInitError)
+  {
+    Werror("dld init error %d",dlInitError);
+  }
+  else
+  {
+    dld_errno=0;
+    int i= dld_link (fn);
+    if (dld_function_executable_p(pn))
+    {
+      p1 = (PROC) dld_get_func (pn);
+      p1();
+      return FALSE;
+    }
+    else
+    {
+      Werror("cannot find %s in %s",pn,fn);
+      dld_unlink_by_file (fn,0);
+    }
+  }
+  #endif
+  /*======================hpux dl============================*/
+  #elif defined(hpux)
+  shl_t hdl=shl_load(fn,
+          BIND_IMMEDIATE|BIND_NOSTART|BIND_NONFATAL|BIND_VERBOSE,0L);
+  int i=shl_findsym(&hdl,pn,TYPE_PROCEDURE,&p1);
+  if (i==0)
+  {
+    p1();
+    return FALSE;
+  }
+  else
+  {
+    Werror("cannot find %s in %s",pn,fn);
+    shl_unload(hdl);
+  }
+  /*=================systems without dynamic loading================*/
+  #else
+  WerrorS("dynamic loading not implemented");
+  #endif
+  return TRUE;
+}
+sleftv * iiMake_binary(idhdl pn, sleftv* sl)
+{
+  return NULL;
+}
+#endif
Index: kernel/sing_dld.h
===================================================================
--- kernel/sing_dld.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/sing_dld.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,27 @@
+#ifndef SING_DLD_H
+#define SING_DLD_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: sing_dld.h,v 1.1.1.1 2003-10-06 12:16:03 Singular Exp $ */
+/*
+* ABSTRACT: dynamic loader
+*/
+
+#ifdef HAVE_DLD
+  sleftv * iiMake_binary(idhdl pn, sleftv* sl);
+  BOOLEAN dlLoad(char * fn, char *pn);
+  #ifdef linux
+    #ifdef __ELF__
+      #define dlInit(A)
+    #else
+      void    dlInit(const char *thisfile);
+    #endif
+  #else
+    #define   dlInit(A)
+  #endif
+  BOOLEAN dlUnload(char * fn, char *pn);
+#else
+  #define   dlInit(A)
+#endif
+#endif
Index: kernel/sing_win.cc
===================================================================
--- kernel/sing_win.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/sing_win.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,77 @@
+#include "mod2.h"
+#ifdef ix86_Win
+#include <windows.h>
+#include <winuser.h>
+#include <sys/cygwin.h>
+#include <stdio.h>
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+
+void heOpenWinntHlp(const char* keyw, char* helppath )
+{
+  char path[MAXPATHLEN];
+#ifdef TEST
+  printf("keyw:%s\n", keyw);
+#endif
+  cygwin_conv_to_full_win32_path(helppath, path);
+#ifdef TEST
+  printf("path:%s\n", path);
+#endif
+      WinHelp(NULL, path, HELP_PARTIALKEY,(DWORD)keyw);
+}
+
+void heOpenWinntUrl(const char* url, int local)
+{
+#ifdef TEST
+  printf("url:%s:local:%d\n", url, local);
+#endif
+  if (local)
+  {
+    char path[MAXPATHLEN];
+    char *p;
+    cygwin_conv_to_full_win32_path(url, path);
+    /* seems like I can not open url's wit # at the end */
+    if ((p=strchr(path, '#')) != NULL) *p = '\0';
+#ifdef TEST
+    printf("path:%s:local:%d\n", path, local);
+#endif
+    ShellExecute(NULL, "open", path, 0, 0, SW_SHOWNORMAL);
+  }
+  else
+  {
+    // need to check whether this works
+    ShellExecute(NULL, "open", url, 0, 0, SW_SHOWNORMAL);
+  }
+}
+
+void *dynl_open(char *filename)
+{
+  char path[MAXPATHLEN];
+  cygwin_conv_to_full_win32_path(filename, path);
+  HINSTANCE hLibrary = LoadLibrary( TEXT(path));
+
+  return(hLibrary);
+}
+
+void *dynl_sym(void *handle, char *symbol)
+{
+  FARPROC f;
+  f = GetProcAddress((HINSTANCE)handle, TEXT (symbol));
+  return(f);
+}
+
+int dynl_close (void *handle)
+{
+  FreeLibrary((HINSTANCE)handle);
+  return(0);
+}
+
+const char *dynl_error()
+{
+  static char errmsg[] = "support for dynamic loading not implemented";
+
+  return errmsg;
+}
+
+#endif /*ix86_Win */
Index: kernel/sing_win.h
===================================================================
--- kernel/sing_win.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/sing_win.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,10 @@
+#ifndef SING_WIN_H
+#define SING_WIN_H
+
+#ifdef ix86_Win
+
+void heOpenWinntHlp(const char* keyw, char* helppath );
+void heOpenWinntUrl(const char* url, int local);
+
+#endif /*ix86_Win */
+#endif /* SING_WIN_H */
Index: kernel/sparsmat.cc
===================================================================
--- kernel/sparsmat.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/sparsmat.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,3158 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: sparsmat.cc,v 1.1.1.1 2003-10-06 12:15:55 Singular Exp $ */
+
+/*
+* ABSTRACT: operations with sparse matrices (bareiss, ...)
+*/
+
+#include "mod2.h"
+#include "structs.h"
+#include "febase.h"
+#include "structs.h"
+#include "intvec.h"
+#include "ring.h"
+#include "polys.h"
+#include "ideals.h"
+#include "numbers.h"
+#include "sparsmat.h"
+#include "prCopy.h"
+#include "p_Procs.h"
+#include "kbuckets.h"
+#include "p_Mult_q.h"
+
+// define SM_NO_BUCKETS, if sparsemat stuff should not use buckets
+// #define SM_NO_BUCKETS
+
+// this is also influenced by TEST_OPT_NOTBUCKETS
+#ifndef SM_NO_BUCKETS
+// buckets do carry a small additional overhead: only use them if
+// min-length of polys is >= SM_MIN_LENGTH_BUCKET
+#define SM_MIN_LENGTH_BUCKET MIN_LENGTH_BUCKET - 5
+#else
+#define SM_MIN_LENGTH_BUCKET    INT_MAX
+#endif
+
+
+/* declare internal 'C' stuff */
+static void smExactPolyDiv(poly, poly);
+static BOOLEAN smIsNegQuot(poly, const poly, const poly);
+static void smExpMultDiv(poly, const poly, const poly);
+static void smPolyDivN(poly, const number);
+static BOOLEAN smSmaller(poly, poly);
+static void smCombineChain(poly *, poly);
+static void smFindRef(poly *, poly *, poly);
+
+static void smElemDelete(smpoly *);
+static smpoly smElemCopy(smpoly);
+static float smPolyWeight(smpoly);
+static smpoly smPoly2Smpoly(poly);
+static poly smSmpoly2Poly(smpoly);
+static BOOLEAN smHaveDenom(poly);
+static number smCleardenom(ideal);
+
+static poly pp_Mult_Coeff_mm_DivSelect_MultDiv(poly p, int &lp, poly m,
+                                               poly a, poly b)
+{
+  if (rOrd_is_Comp_dp(currRing) && currRing->ExpL_Size > 2)
+  {
+    // pp_Mult_Coeff_mm_DivSelectMult only works for (c/C,dp) and
+    // ExpL_Size > 2
+    // should be generalized, at least to dp with ExpL_Size == 2
+    // (is the case for 1 variable)
+    int shorter;
+    p = currRing->p_Procs->pp_Mult_Coeff_mm_DivSelectMult(p, m, a, b,
+                                                          shorter, currRing);
+    lp -= shorter;
+  }
+  else
+  {
+    p = pp_Mult_Coeff_mm_DivSelect(p, lp, m, currRing);
+    smExpMultDiv(p, a, b);
+  }
+  return p;
+}
+
+static poly smSelectCopy_ExpMultDiv(poly p, poly m, poly a, poly b)
+{
+  int lp = 0;
+  return pp_Mult_Coeff_mm_DivSelect_MultDiv(p, lp, m, a, b);
+}
+
+
+/* class for sparse matrix:
+*      3 parts of matrix during the algorithm
+*      m_act[cols][pos(rows)] => m_row[rows][pos(cols)] => m_res[cols][pos(rows)]
+*      input                     pivotcols as rows         result
+*      pivot                     like a stack              from pivot and pivotcols
+*      elimination                                         rows reordered according
+*                                                          to pivot choise
+*                                                          stored in perm
+*      a step is as follows
+*      - search of pivot (smPivot)
+*      - swap pivot column and last column (smSwapC)
+*        select pivotrow to piv and red (smSelectPR)
+*        consider sign
+*      - elimination (smInitElim, sm0Elim, sm1Elim)
+*        clear zero column as result of elimination (smZeroElim)
+*      - tranfer from
+*        piv and m_row to m_res (smRowToCol)
+*        m_act to m_row (smColToRow)
+*/
+class sparse_mat{
+private:
+  int nrows, ncols;    // dimension of the problem
+  int sign;            // for determinant (start: 1)
+  int act;             // number of unreduced columns (start: ncols)
+  int crd;             // number of reduced columns (start: 0)
+  int tored;           // border for rows to reduce
+  int inred;           // unreducable part
+  int rpiv, cpiv;      // position of the pivot
+  int normalize;       // Normalization flag
+  int *perm;           // permutation of rows
+  float wpoints;       // weight of all points
+  float *wrw, *wcl;    // weights of rows and columns
+  smpoly * m_act;      // unreduced columns
+  smpoly * m_res;      // reduced columns (result)
+  smpoly * m_row;      // reduced part of rows
+  smpoly red;          // row to reduce
+  smpoly piv, oldpiv;  // pivot and previous pivot
+  smpoly dumm;         // allocated dummy
+  void smColToRow();
+  void smRowToCol();
+  void smFinalMult();
+  void smSparseHomog();
+  void smWeights();
+  void smPivot();
+  void smNewWeights();
+  void smNewPivot();
+  void smZeroElim();
+  void smToredElim();
+  void smCopToRes();
+  void smSelectPR();
+  void smElim();
+  void sm1Elim();
+  void smHElim();
+  void smMultCol();
+  poly smMultPoly(smpoly);
+  void smActDel();
+  void smColDel();
+  void smPivDel();
+  void smSign();
+  void smInitPerm();
+  int smCheckNormalize();
+  void smNormalize();
+public:
+  sparse_mat(ideal);
+  ~sparse_mat();
+  int smGetSign() { return sign; }
+  smpoly * smGetAct() { return m_act; }
+  int smGetRed() { return tored; }
+  ideal smRes2Mod();
+  poly smDet();
+  void smBareiss(int, int);
+  void smNewBareiss(int, int);
+  void smToIntvec(intvec *);
+};
+
+/*
+* estimate maximal exponent for det or minors,
+* the module m has di vectors and maximal rank ra,
+* estimate yields for the tXt minors,
+* we have di,ra >= t
+*/
+static void smMinSelect(Exponent_t *, int, int);
+Exponent_t smExpBound( ideal m, int di, int ra, int t)
+{
+  poly p;
+  Exponent_t kr, kc;
+  Exponent_t *r, *c;
+  int al, bl, i, j, k;
+
+  if (ra==0) ra=1;
+  al = di*sizeof(Exponent_t);
+  c = (Exponent_t *)omAlloc(al);
+  bl = ra*sizeof(Exponent_t);
+  r = (Exponent_t *)omAlloc0(bl);
+  for (i=di-1;i>=0;i--)
+  {
+    kc = 0;
+    p = m->m[i];
+    while(p!=NULL)
+    {
+      k = pGetComp(p)-1;
+      kr = r[k];
+      for (j=pVariables;j>0;j--)
+      {
+        if(pGetExp(p,j)>kc)
+          kc=pGetExp(p,j);
+        if(pGetExp(p,j)>kr)
+          kr=pGetExp(p,j);
+      }
+      r[k] = kr;
+      pIter(p);
+    }
+    c[i] = kc;
+  }
+  if (t<di) smMinSelect(c, t, di);
+  if (t<ra) smMinSelect(r, t, ra);
+  kr = kc = 0;
+  for (j=t-1;j>=0;j--)
+  {
+    kr += r[j];
+    kc += c[j];
+  }
+  omFreeSize((ADDRESS)c, al);
+  omFreeSize((ADDRESS)r, bl);
+  if (kr<kc) kc = kr;
+  if (kr<1) kr = 1;
+  return kr;
+}
+
+static void smMinSelect(Exponent_t *c, int t, int d)
+{
+  Exponent_t m;
+  int pos, i;
+  do
+  {
+    d--;
+    pos = d;
+    m = c[pos];
+    for (i=d-1;i>=0;i--)
+    {
+      if(c[i]<m)
+      {
+        pos = i;
+        m = c[i];
+      }
+    }
+    for (i=pos;i<d;i++) c[i] = c[i+1];
+  } while (d>t);
+}
+
+/* ----------------- ops with rings ------------------ */
+void smRingChange(ring *origR, sip_sring &tmpR, Exponent_t bound)
+{
+  *origR =currRing;
+  tmpR=*currRing;
+  int *ord=(int*)omAlloc0(3*sizeof(int));
+  int *block0=(int*)omAlloc(3*sizeof(int));
+  int *block1=(int*)omAlloc(3*sizeof(int));
+  ord[0]=ringorder_c;
+  ord[1]=ringorder_dp;
+  tmpR.order=ord;
+  tmpR.OrdSgn=1;
+  block0[1]=1;
+  tmpR.block0=block0;
+  block1[1]=tmpR.N;
+  tmpR.block1=block1;
+  tmpR.bitmask = bound;
+
+// ???
+//  if (tmpR.bitmask > currRing->bitmask) tmpR.bitmask = currRing->bitmask;
+
+  rComplete(&tmpR,1);
+  rChangeCurrRing(&tmpR);
+  if (TEST_OPT_PROT)
+    Print("[%d:%d]", (long) tmpR.bitmask, tmpR.ExpL_Size);
+}
+
+void smRingClean(ring origR, ip_sring &tmpR)
+{
+  rUnComplete(&tmpR);
+  omFreeSize((ADDRESS)tmpR.order,3*sizeof(int));
+  omFreeSize((ADDRESS)tmpR.block0,3*sizeof(int));
+  omFreeSize((ADDRESS)tmpR.block1,3*sizeof(int));
+}
+
+/*2
+* Bareiss or Chinese remainder ?
+* I is dXd
+* sw = TRUE  -> I Matrix
+*      FALSE -> I Module
+* return True  -> change Type
+*        FALSE -> same Type
+*/
+BOOLEAN smCheckDet(ideal I, int d, BOOLEAN sw)
+{
+  int s,t,i;
+  poly p;
+
+  if ((d>100) || (currRing->parameter!=NULL))
+    return sw;
+  if (rField_is_Q(currRing)==FALSE)
+    return sw;
+  s = t = 0;
+  if (sw)
+  {
+    for(i=IDELEMS(I)-1;i>=0;i--)
+    {
+      p=I->m[i];
+      if (p!=NULL)
+      {
+        if(!pIsConstant(p))
+          return sw;
+        s++;
+        t+=nSize(pGetCoeff(p));
+      }
+    }
+  }
+  else
+  {
+    for(i=IDELEMS(I)-1;i>=0;i--)
+    {
+      p=I->m[i];
+      if (!pIsConstantPoly(p))
+        return sw;
+      while (p!=NULL)
+      {
+        s++;
+        t+=nSize(pGetCoeff(p));
+        pIter(p);
+      }
+    }
+  }
+  s*=15;
+  if (t>s)
+    return !sw;
+  else
+    return sw;
+}
+
+/* ----------------- basics (used from 'C') ------------------ */
+/*2
+*returns the determinant of the module I;
+*uses Bareiss algorithm
+*/
+poly smCallDet(ideal I)
+{
+  if (I->ncols != I->rank)
+  {
+    Werror("det of %d x %d module (matrix)",I->rank,I->ncols);
+    return NULL;
+  }
+  int r=idRankFreeModule(I);
+  if (I->ncols != r) // some 0-lines at the end
+  {
+    return NULL;
+  }
+  Exponent_t bound=smExpBound(I,r,r,r);
+  number diag,h=nInit(1);
+  poly res;
+  ring origR;
+  sip_sring tmpR;
+  sparse_mat *det;
+  ideal II;
+
+  smRingChange(&origR,tmpR,bound);
+  II = idrCopyR(I, origR);
+  diag = smCleardenom(II);
+  det = new sparse_mat(II);
+  idDelete(&II);
+  if (det->smGetAct() == NULL)
+  {
+    delete det;
+    rChangeCurrRing(origR);
+    smRingClean(origR,tmpR);
+    return NULL;
+  }
+  res=det->smDet();
+  if(det->smGetSign()<0) res=pNeg(res);
+  delete det;
+  rChangeCurrRing(origR);
+  res = prMoveR(res, &tmpR);
+  smRingClean(origR,tmpR);
+  if (nEqual(diag,h) == FALSE)
+  {
+    pMult_nn(res,diag);
+    pNormalize(res);
+  }
+  nDelete(&diag);
+  nDelete(&h);
+  return res;
+}
+
+void smCallBareiss(ideal I, int x, int y, ideal &M, intvec ** iv)
+{
+  int r=idRankFreeModule(I),t=r;
+  int c=IDELEMS(I),s=c;
+  Exponent_t bound;
+  ring origR;
+  sip_sring tmpR;
+  sparse_mat *bareiss;
+
+  if ((x>0) && (x<t))
+    t-=x;
+  if ((y>1) && (y<s))
+    s-=y;
+  if (t>s) t=s;
+  bound=2*smExpBound(I,c,r,t);
+  smRingChange(&origR,tmpR,bound);
+  ideal II = idrCopyR(I, origR);
+  bareiss = new sparse_mat(II);
+  if (bareiss->smGetAct() == NULL)
+  {
+    delete bareiss;
+    *iv=new intvec(1,pVariables);
+    rChangeCurrRing(origR);
+  }
+  else
+  {
+    idDelete(&II);
+    bareiss->smBareiss(x, y);
+    II = bareiss->smRes2Mod();
+    *iv = new intvec(bareiss->smGetRed());
+    bareiss->smToIntvec(*iv);
+    delete bareiss;
+    rChangeCurrRing(origR);
+    II = idrMoveR(II,&tmpR);
+  }
+  smRingClean(origR,tmpR);
+  M=II;
+}
+
+void smCallNewBareiss(ideal I, int x, int y, ideal & M, intvec **iv)
+{
+  int r=idRankFreeModule(I),t=r;
+  int c=IDELEMS(I),s=c;
+  Exponent_t bound;
+  ring origR;
+  sip_sring tmpR;
+  sparse_mat *bareiss;
+
+  if ((x>0) && (x<t))
+    t-=x;
+  if ((y>1) && (y<s))
+    s-=y;
+  if (t>s) t=s;
+  bound=smExpBound(I,c,r,t);
+  smRingChange(&origR,tmpR,bound);
+  ideal II = idrCopyR(I, origR);
+  bareiss = new sparse_mat(II);
+  if (bareiss->smGetAct() == NULL)
+  {
+    delete bareiss;
+    *iv=new intvec(1,pVariables);
+    rChangeCurrRing(origR);
+  }
+  else
+  {
+    idDelete(&II);
+    bareiss->smNewBareiss(x, y);
+    II = bareiss->smRes2Mod();
+    *iv = new intvec(bareiss->smGetRed());
+    bareiss->smToIntvec(*iv);
+    delete bareiss;
+    rChangeCurrRing(origR);
+    II = idrMoveR(II,&tmpR);
+  }
+  smRingClean(origR,tmpR);
+  M=II;
+}
+
+/*
+* constructor
+*/
+sparse_mat::sparse_mat(ideal smat)
+{
+  int i;
+  polyset pmat;
+
+  ncols = smat->ncols;
+  nrows = idRankFreeModule(smat);
+  if (nrows <= 0)
+  {
+    m_act = NULL;
+    return;
+  }
+  sign = 1;
+  inred = act = ncols;
+  crd = 0;
+  tored = nrows; // without border
+  i = tored+1;
+  perm = (int *)omAlloc(sizeof(int)*(i+1));
+  perm[i] = 0;
+  m_row = (smpoly *)omAlloc0(sizeof(smpoly)*i);
+  wrw = (float *)omAlloc(sizeof(float)*i);
+  i = ncols+1;
+  wcl = (float *)omAlloc(sizeof(float)*i);
+  m_act = (smpoly *)omAlloc(sizeof(smpoly)*i);
+  m_res = (smpoly *)omAlloc0(sizeof(smpoly)*i);
+  dumm = (smpoly)omAllocBin(smprec_bin);
+  m_res[0] = (smpoly)omAllocBin(smprec_bin);
+  m_res[0]->m = NULL;
+  pmat = smat->m;
+  for(i=ncols; i; i--)
+  {
+    m_act[i] = smPoly2Smpoly(pmat[i-1]);
+    pmat[i-1] = NULL;
+  }
+  this->smZeroElim();
+  oldpiv = NULL;
+}
+
+/*
+* destructor
+*/
+sparse_mat::~sparse_mat()
+{
+  int i;
+  if (m_act == NULL) return;
+  omFreeBin((ADDRESS)m_res[0],  smprec_bin);
+  omFreeBin((ADDRESS)dumm,  smprec_bin);
+  i = ncols+1;
+  omFreeSize((ADDRESS)m_res, sizeof(smpoly)*i);
+  omFreeSize((ADDRESS)m_act, sizeof(smpoly)*i);
+  omFreeSize((ADDRESS)wcl, sizeof(float)*i);
+  i = nrows+1;
+  omFreeSize((ADDRESS)wrw, sizeof(float)*i);
+  omFreeSize((ADDRESS)m_row, sizeof(smpoly)*i);
+  omFreeSize((ADDRESS)perm, sizeof(int)*(i+1));
+}
+
+/*
+* transform the result to a module
+*/
+ideal sparse_mat::smRes2Mod()
+{
+  ideal res = idInit(crd, crd);
+  int i;
+
+  for (i=crd; i; i--) res->m[i-1] = smSmpoly2Poly(m_res[i]);
+  res->rank = idRankFreeModule(res);
+  return res;
+}
+
+/*
+* permutation of rows
+*/
+void sparse_mat::smToIntvec(intvec *v)
+{
+  int i;
+
+  for (i=v->rows()-1; i>=0; i--)
+    (*v)[i] = perm[i+1];
+}
+/* ---------------- the algorithm's ------------------ */
+/*
+* the determinant (up to sign), uses new Bareiss elimination
+*/
+poly sparse_mat::smDet()
+{
+  int y;
+  poly res = NULL;
+
+  if (sign == 0)
+  {
+    this->smActDel();
+    return NULL;
+  }
+  if (act < 2)
+  {
+    if (act != 0) res = m_act[1]->m;
+    omFreeBin((void *)m_act[1],  smprec_bin);
+    return res;
+  }
+  normalize = 0;
+  this->smInitPerm();
+  this->smPivot();
+  this->smSign();
+  this->smSelectPR();
+  this->sm1Elim();
+  crd++;
+  m_res[crd] = piv;
+  this->smColDel();
+  act--;
+  this->smZeroElim();
+  if (sign == 0)
+  {
+    this->smActDel();
+    return NULL;
+  }
+  if (act < 2)
+  {
+    this->smFinalMult();
+    this->smPivDel();
+    if (act != 0) res = m_act[1]->m;
+    omFreeBin((void *)m_act[1],  smprec_bin);
+    return res;
+  }
+  loop
+  {
+    this->smNewPivot();
+    this->smSign();
+    this->smSelectPR();
+    this->smMultCol();
+    this->smHElim();
+    crd++;
+    m_res[crd] = piv;
+    this->smColDel();
+    act--;
+    this->smZeroElim();
+    if (sign == 0)
+    {
+      this->smPivDel();
+      this->smActDel();
+      return NULL;
+    }
+    if (act < 2)
+    {
+      if (TEST_OPT_PROT) PrintS(".\n");
+      this->smFinalMult();
+      this->smPivDel();
+      if (act != 0) res = m_act[1]->m;
+      omFreeBin((void *)m_act[1],  smprec_bin);
+      return res;
+    }
+  }
+}
+
+/*
+* the Bareiss elimination:
+*   - with x unreduced last rows, pivots from here are not allowed
+*   - the method will finish for number of unreduced columns < y
+*/
+void sparse_mat::smBareiss(int x, int y)
+{
+  if ((x > 0) && (x < nrows))
+  {
+    tored -= x;
+    this->smToredElim();
+  }
+  if (y < 1) y = 1;
+  if (act <= y)
+  {
+    this->smCopToRes();
+    return;
+  }
+  normalize = this->smCheckNormalize();
+  if (normalize) this->smNormalize();
+  this->smPivot();
+  this->smSelectPR();
+  this->smElim();
+  crd++;
+  this->smColToRow();
+  act--;
+  this->smRowToCol();
+  this->smZeroElim();
+  if (tored != nrows)
+    this->smToredElim();
+  if (act < y)
+  {
+    this->smCopToRes();
+    return;
+  }
+  loop
+  {
+    if (normalize) this->smNormalize();
+    this->smPivot();
+    oldpiv = piv;
+    this->smSelectPR();
+    this->smElim();
+    crd++;
+    this->smColToRow();
+    act--;
+    this->smRowToCol();
+    this->smZeroElim();
+    if (tored != nrows)
+      this->smToredElim();
+    if (act < y)
+    {
+      if (TEST_OPT_PROT) PrintS(".\n");
+      this->smCopToRes();
+      return;
+    }
+  }
+}
+
+/*
+* the new Bareiss elimination:
+*   - with x unreduced last rows, pivots from here are not allowed
+*   - the method will finish for number of unreduced columns < y
+*/
+void sparse_mat::smNewBareiss(int x, int y)
+{
+  if ((x > 0) && (x < nrows))
+  {
+    tored -= x;
+    this->smToredElim();
+  }
+  if (y < 1) y = 1;
+  if (act <= y)
+  {
+    this->smCopToRes();
+    return;
+  }
+  normalize = this->smCheckNormalize();
+  if (normalize) this->smNormalize();
+  this->smPivot();
+  this->smSelectPR();
+  this->sm1Elim();
+  crd++;
+  this->smColToRow();
+  act--;
+  this->smRowToCol();
+  this->smZeroElim();
+  if (tored != nrows)
+    this->smToredElim();
+  if (act <= y)
+  {
+    this->smFinalMult();
+    this->smCopToRes();
+    return;
+  }
+  loop
+  {
+    if (normalize) this->smNormalize();
+    this->smNewPivot();
+    this->smSelectPR();
+    this->smMultCol();
+    this->smHElim();
+    crd++;
+    this->smColToRow();
+    act--;
+    this->smRowToCol();
+    this->smZeroElim();
+    if (tored != nrows)
+      this->smToredElim();
+    if (act <= y)
+    {
+      if (TEST_OPT_PROT) PrintS(".\n");
+      this->smFinalMult();
+      this->smCopToRes();
+      return;
+    }
+  }
+}
+
+/* ----------------- pivot method ------------------ */
+
+/*
+* prepare smPivot, compute weights for rows and columns
+* and the weight for all points
+*/
+void sparse_mat::smWeights()
+{
+  float wc, wp, w;
+  smpoly a;
+  int i;
+
+  wp = 0.0;
+  for (i=tored; i; i--) wrw[i] = 0.0; // ???
+  for (i=act; i; i--)
+  {
+    wc = 0.0;
+    a = m_act[i];
+    loop
+    {
+      if (a->pos > tored)
+        break;
+      w = a->f = smPolyWeight(a);
+      wc += w;
+      wrw[a->pos] += w;
+      a = a->n;
+      if (a == NULL)
+        break;
+    }
+    wp += wc;
+    wcl[i] = wc;
+  }
+  wpoints = wp;
+}
+
+/*
+* compute pivot
+*/
+void sparse_mat::smPivot()
+{
+  float wopt = 1.0e30;
+  float wc, wr, wp, w;
+  smpoly a;
+  int i, copt, ropt;
+
+  this->smWeights();
+  for (i=act; i; i--)
+  {
+    a = m_act[i];
+    loop
+    {
+      if (a->pos > tored)
+        break;
+      w = a->f;
+      wc = wcl[i]-w;
+      wr = wrw[a->pos]-w;
+      if ((wr<0.25) || (wc<0.25)) // row or column with only one point
+      {
+        if (w<wopt)
+        {
+          wopt = w;
+          copt = i;
+          ropt = a->pos;
+        }
+      }
+      else // elimination
+      {
+        wp = w*(wpoints-wcl[i]-wr);
+        wp += wr*wc;
+        if (wp < wopt)
+        {
+          wopt = wp;
+          copt = i;
+          ropt = a->pos;
+        }
+      }
+      a = a->n;
+      if (a == NULL)
+        break;
+    }
+  }
+  rpiv = ropt;
+  cpiv = copt;
+  if (cpiv != act)
+  {
+    a = m_act[act];
+    m_act[act] = m_act[cpiv];
+    m_act[cpiv] = a;
+  }
+}
+
+/*
+* prepare smPivot, compute weights for rows and columns
+* and the weight for all points
+*/
+void sparse_mat::smNewWeights()
+{
+  float wc, wp, w, hp = piv->f;
+  smpoly a;
+  int i, f, e = crd;
+
+  wp = 0.0;
+  for (i=tored; i; i--) wrw[i] = 0.0; // ???
+  for (i=act; i; i--)
+  {
+    wc = 0.0;
+    a = m_act[i];
+    loop
+    {
+      if (a->pos > tored)
+        break;
+      w = a->f;
+      f = a->e;
+      if (f < e)
+      {
+        w *= hp;
+        if (f) w /= m_res[f]->f;
+      }
+      wc += w;
+      wrw[a->pos] += w;
+      a = a->n;
+      if (a == NULL)
+        break;
+    }
+    wp += wc;
+    wcl[i] = wc;
+  }
+  wpoints = wp;
+}
+
+/*
+* compute pivot
+*/
+void sparse_mat::smNewPivot()
+{
+  float wopt = 1.0e30, hp = piv->f;
+  float wc, wr, wp, w;
+  smpoly a;
+  int i, copt, ropt, f, e = crd;
+
+  this->smNewWeights();
+  for (i=act; i; i--)
+  {
+    a = m_act[i];
+    loop
+    {
+      if (a->pos > tored)
+        break;
+      w = a->f;
+      f = a->e;
+      if (f < e)
+      {
+        w *= hp;
+        if (f) w /= m_res[f]->f;
+      }
+      wc = wcl[i]-w;
+      wr = wrw[a->pos]-w;
+      if ((wr<0.25) || (wc<0.25)) // row or column with only one point
+      {
+        if (w<wopt)
+        {
+          wopt = w;
+          copt = i;
+          ropt = a->pos;
+        }
+      }
+      else // elimination
+      {
+        wp = w*(wpoints-wcl[i]-wr);
+        wp += wr*wc;
+        if (wp < wopt)
+        {
+          wopt = wp;
+          copt = i;
+          ropt = a->pos;
+        }
+      }
+      a = a->n;
+      if (a == NULL)
+        break;
+    }
+  }
+  rpiv = ropt;
+  cpiv = copt;
+  if (cpiv != act)
+  {
+    a = m_act[act];
+    m_act[act] = m_act[cpiv];
+    m_act[cpiv] = a;
+  }
+}
+
+/* ----------------- elimination ------------------ */
+
+/* steps of elimination */
+void sparse_mat::smElim()
+{
+  poly p = piv->m;        // pivotelement
+  smpoly c = m_act[act];  // pivotcolumn
+  smpoly r = red;         // row to reduce
+  poly q;
+  smpoly res, a, b;
+  poly w, ha, hb;
+  int i;
+
+  if (oldpiv != NULL) q = oldpiv->m; // previous pivot
+  else q = NULL;
+  if ((c == NULL) || (r == NULL))
+  {
+    while (r) smElemDelete(&r);
+    for (i=1; i<act; i++)
+    {
+      a = m_act[i];
+      while (a != NULL)
+      {
+        ha = SM_MULT(a->m, p, q);
+        pDelete(&a->m);
+        if (q) SM_DIV(ha, q);
+        a->m = ha;
+        a = a->n;
+      }
+    }
+    return;
+  }
+  for (i=1; i<act; i++)
+  {
+    a = m_act[i];
+    if ((r == NULL) || (i != r->pos))  // cols without elimination
+    {
+      while (a != NULL)
+      {
+        ha = SM_MULT(a->m, p, q);
+        pDelete(&a->m);
+        if (q) SM_DIV(ha, q);
+        a->m = ha;
+        a = a->n;
+      }
+    }
+    else                    // cols with elimination
+    {
+      res = dumm;
+      res->n = NULL;
+      b = c;
+      w = r->m;
+      loop                  // combine the chains a and b: p*a + w*b
+      {
+        if (a == NULL)
+        {
+          if (b != NULL)
+          {
+            do
+            {
+              res = res->n = smElemCopy(b);
+              hb = SM_MULT(b->m, w, q);
+              if (q) SM_DIV(hb, q);
+              res->m = hb;
+              b = b->n;
+            } while (b != NULL);
+          }
+          else
+            res->n = NULL;
+          break;
+        }
+        if (b == NULL)
+        {
+          do
+          {
+            ha = SM_MULT(a->m, p, q);
+            pDelete(&a->m);
+            if (q) SM_DIV(ha, q);
+            a->m = ha;
+            res = res->n = a;
+            a = a->n;
+          } while (a != NULL);
+          break;
+        }
+        if (a->pos < b->pos)
+        {
+          ha = SM_MULT(a->m, p, q);
+          pDelete(&a->m);
+          if (q) SM_DIV(ha, q);
+          a->m = ha;
+          res = res->n = a;
+          a = a->n;
+        }
+        else if (a->pos > b->pos)
+        {
+          res = res->n = smElemCopy(b);
+          hb = SM_MULT(b->m, w, q);
+          b = b->n;
+          if (q) SM_DIV(hb, q);
+          res->m = hb;
+        }
+        else
+        {
+          ha = SM_MULT(a->m, p, q);
+          pDelete(&a->m);
+          hb = SM_MULT(b->m, w, q);
+          ha = pAdd(ha, hb);
+          if (ha != NULL)
+          {
+            if (q) SM_DIV(ha, q);
+            a->m = ha;
+            res = res->n = a;
+            a = a->n;
+          }
+          else
+          {
+            smElemDelete(&a);
+          }
+          b = b->n;
+        }
+      }
+      m_act[i] = dumm->n;
+      if (r) smElemDelete(&r);
+    }
+  }
+}
+
+/* first step of elimination */
+void sparse_mat::sm1Elim()
+{
+  poly p = piv->m;        // pivotelement
+  smpoly c = m_act[act];  // pivotcolumn
+  smpoly r = red;         // row to reduce
+  smpoly res, a, b;
+  poly w, ha, hb;
+
+  if ((c == NULL) || (r == NULL))
+  {
+    while (r!=NULL) smElemDelete(&r);
+    return;
+  }
+  do
+  {
+    a = m_act[r->pos];
+    res = dumm;
+    res->n = NULL;
+    b = c;
+    w = r->m;
+    loop                  // combine the chains a and b: p*a + w*b
+    {
+      if (a == NULL)
+      {
+        do
+        {
+          res = res->n = smElemCopy(b);
+          res->m = ppMult_qq(b->m, w);
+          res->e = 1;
+          res->f = smPolyWeight(res);
+          b = b->n;
+        } while (b != NULL);
+        break;
+      }
+      if (a->pos < b->pos)
+      {
+        res = res->n = a;
+        a = a->n;
+      }
+      else if (a->pos > b->pos)
+      {
+        res = res->n = smElemCopy(b);
+        res->m = ppMult_qq(b->m, w);
+        res->e = 1;
+        res->f = smPolyWeight(res);
+        b = b->n;
+      }
+      else
+      {
+        ha = ppMult_qq(a->m, p);
+        pDelete(&a->m);
+        hb = ppMult_qq(b->m, w);
+        ha = pAdd(ha, hb);
+        if (ha != NULL)
+        {
+          a->m = ha;
+          a->e = 1;
+          a->f = smPolyWeight(a);
+          res = res->n = a;
+          a = a->n;
+        }
+        else
+        {
+          smElemDelete(&a);
+        }
+        b = b->n;
+      }
+      if (b == NULL)
+      {
+        res->n = a;
+        break;
+      }
+    }
+    m_act[r->pos] = dumm->n;
+    smElemDelete(&r);
+  } while (r != NULL);
+}
+
+/* higher steps of elimination */
+void sparse_mat::smHElim()
+{
+  poly hp = this->smMultPoly(piv);
+  poly gp = piv->m;       // pivotelement
+  smpoly c = m_act[act];  // pivotcolumn
+  smpoly r = red;         // row to reduce
+  smpoly res, a, b;
+  poly ha, hr, x, y;
+  int e, ip, ir, ia, lev;
+
+  if ((c == NULL) || (r == NULL))
+  {
+    while(r!=NULL) smElemDelete(&r);
+    pDelete(&hp);
+    return;
+  }
+  e = crd+1;
+  ip = piv->e;
+  do
+  {
+    a = m_act[r->pos];
+    res = dumm;
+    res->n = NULL;
+    b = c;
+    hr = r->m;
+    ir = r->e;
+    loop                  // combine the chains a and b: (hp,gp)*a(l) + hr*b(h)
+    {
+      if (a == NULL)
+      {
+        do
+        {
+          res = res->n = smElemCopy(b);
+          x = SM_MULT(b->m, hr, m_res[ir]->m);
+          b = b->n;
+          if(ir) SM_DIV(x, m_res[ir]->m);
+          res->m = x;
+          res->e = e;
+          res->f = smPolyWeight(res);
+        } while (b != NULL);
+        break;
+      }
+      if (a->pos < b->pos)
+      {
+        res = res->n = a;
+        a = a->n;
+      }
+      else if (a->pos > b->pos)
+      {
+        res = res->n = smElemCopy(b);
+        x = SM_MULT(b->m, hr, m_res[ir]->m);
+        b = b->n;
+        if(ir) SM_DIV(x, m_res[ir]->m);
+        res->m = x;
+        res->e = e;
+        res->f = smPolyWeight(res);
+      }
+      else
+      {
+        ha = a->m;
+        ia = a->e;
+        if (ir >= ia)
+        {
+          if (ir > ia)
+          {
+            x = SM_MULT(ha, m_res[ir]->m, m_res[ia]->m);
+            pDelete(&ha);
+            ha = x;
+            if (ia) SM_DIV(ha, m_res[ia]->m);
+            ia = ir;
+          }
+          x = SM_MULT(ha, gp, m_res[ia]->m);
+          pDelete(&ha);
+          y = SM_MULT(b->m, hr, m_res[ia]->m);
+        }
+        else if (ir >= ip)
+        {
+          if (ia < crd)
+          {
+            x = SM_MULT(ha, m_res[crd]->m, m_res[ia]->m);
+            pDelete(&ha);
+            ha = x;
+            SM_DIV(ha, m_res[ia]->m);
+          }
+          y = hp;
+          if(ir > ip)
+          {
+            y = SM_MULT(y, m_res[ir]->m, m_res[ip]->m);
+            if (ip) SM_DIV(y, m_res[ip]->m);
+          }
+          ia = ir;
+          x = SM_MULT(ha, y, m_res[ia]->m);
+          if (y != hp) pDelete(&y);
+          pDelete(&ha);
+          y = SM_MULT(b->m, hr, m_res[ia]->m);
+        }
+        else
+        {
+          x = SM_MULT(hr, m_res[ia]->m, m_res[ir]->m);
+          if (ir) SM_DIV(x, m_res[ir]->m);
+          y = SM_MULT(b->m, x, m_res[ia]->m);
+          pDelete(&x);
+          x = SM_MULT(ha, gp, m_res[ia]->m);
+          pDelete(&ha);
+        }
+        ha = pAdd(x, y);
+        if (ha != NULL)
+        {
+          if (ia) SM_DIV(ha, m_res[ia]->m);
+          a->m = ha;
+          a->e = e;
+          a->f = smPolyWeight(a);
+          res = res->n = a;
+          a = a->n;
+        }
+        else
+        {
+          a->m = NULL;
+          smElemDelete(&a);
+        }
+        b = b->n;
+      }
+      if (b == NULL)
+      {
+        res->n = a;
+        break;
+      }
+    }
+    m_act[r->pos] = dumm->n;
+    smElemDelete(&r);
+  } while (r != NULL);
+  pDelete(&hp);
+}
+
+/* ----------------- transfer ------------------ */
+
+/*
+* select the pivotrow and store it to red and piv
+*/
+void sparse_mat::smSelectPR()
+{
+  smpoly b = dumm;
+  smpoly a, ap;
+  int i;
+
+  if (TEST_OPT_PROT)
+  {
+    if ((crd+1)%10)
+      PrintS(".");
+    else
+      PrintS(".\n");
+  }
+  a = m_act[act];
+  if (a->pos < rpiv)
+  {
+    do
+    {
+      ap = a;
+      a = a->n;
+    } while (a->pos < rpiv);
+    ap->n = a->n;
+  }
+  else
+    m_act[act] = a->n;
+  piv = a;
+  a->n = NULL;
+  for (i=1; i<act; i++)
+  {
+    a = m_act[i];
+    if (a->pos < rpiv)
+    {
+      loop
+      {
+        ap = a;
+        a = a->n;
+        if ((a == NULL) || (a->pos > rpiv))
+          break;
+        if (a->pos == rpiv)
+        {
+          ap->n = a->n;
+          a->m = pNeg(a->m);
+          b = b->n = a;
+          b->pos = i;
+          break;
+        }
+      }
+    }
+    else if (a->pos == rpiv)
+    {
+      m_act[i] = a->n;
+      a->m = pNeg(a->m);
+      b = b->n = a;
+      b->pos = i;
+    }
+  }
+  b->n = NULL;
+  red = dumm->n;
+}
+
+/*
+* store the pivotcol in m_row
+*   m_act[cols][pos(rows)] => m_row[rows][pos(cols)]
+*/
+void sparse_mat::smColToRow()
+{
+  smpoly c = m_act[act];
+  smpoly h;
+
+  while (c != NULL)
+  {
+    h = c;
+    c = c->n;
+    h->n = m_row[h->pos];
+    m_row[h->pos] = h;
+    h->pos = crd;
+  }
+}
+
+/*
+* store the pivot and the assosiated row in m_row
+* to m_res (result):
+*   piv + m_row[rows][pos(cols)] => m_res[cols][pos(rows)]
+*/
+void sparse_mat::smRowToCol()
+{
+  smpoly r = m_row[rpiv];
+  smpoly a, ap, h;
+
+  m_row[rpiv] = NULL;
+  perm[crd] = rpiv;
+  piv->pos = crd;
+  m_res[crd] = piv;
+  while (r != NULL)
+  {
+    ap = m_res[r->pos];
+    loop
+    {
+      a = ap->n;
+      if (a == NULL)
+      {
+        ap->n = h = r;
+        r = r->n;
+        h->n = a;
+        h->pos = crd;
+        break;
+      }
+      ap = a;
+    }
+  }
+}
+
+/* ----------------- C++ stuff ------------------ */
+
+/*
+*  clean m_act from zeros (after elim)
+*/
+void sparse_mat::smZeroElim()
+{
+  int i = 0;
+  int j;
+
+  loop
+  {
+    i++;
+    if (i > act) return;
+    if (m_act[i] == NULL) break;
+  }
+  j = i;
+  loop
+  {
+    j++;
+    if (j > act) break;
+    if (m_act[j] != NULL)
+    {
+      m_act[i] = m_act[j];
+      i++;
+    }
+  }
+  act -= (j-i);
+  sign = 0;
+}
+
+/*
+*  clean m_act from cols not to reduced (after elim)
+*  put them to m_res
+*/
+void sparse_mat::smToredElim()
+{
+  int i = 0;
+  int j;
+
+  loop
+  {
+    i++;
+    if (i > act) return;
+    if (m_act[i]->pos > tored)
+    {
+      m_res[inred] = m_act[i];
+      inred--;
+      break;
+    }
+  }
+  j = i;
+  loop
+  {
+    j++;
+    if (j > act) break;
+    if (m_act[j]->pos > tored)
+    {
+      m_res[inred] = m_act[j];
+      inred--;
+    }
+    else
+    {
+      m_act[i] = m_act[j];
+      i++;
+    }
+  }
+  act -= (j-i);
+  sign = 0;
+}
+
+/*
+*  copy m_act to m_res
+*/
+void sparse_mat::smCopToRes()
+{
+  smpoly a,ap,r,h;
+  int i,j,k,l;
+
+  i = 0;
+  if (act)
+  {
+    a = m_act[act]; // init perm
+    do
+    {
+      i++;
+      perm[crd+i] = a->pos;
+      a = a->n;
+    } while ((a != NULL) && (a->pos <= tored));
+    for (j=act-1;j;j--) // load all positions of perm
+    {
+      a = m_act[j];
+      k = 1;
+      loop
+      {
+        if (perm[crd+k] >= a->pos)
+        {
+          if (perm[crd+k] > a->pos)
+          {
+            for (l=i;l>=k;l--) perm[crd+l+1] = perm[crd+l];
+            perm[crd+k] = a->pos;
+            i++;
+          }
+          a = a->n;
+          if ((a == NULL) || (a->pos > tored)) break;
+        }
+        k++;
+        if ((k > i) && (a->pos <= tored))
+        {
+          do
+          {
+            i++;
+            perm[crd+i] = a->pos;
+            a = a->n;
+          } while ((a != NULL) && (a->pos <= tored));
+          break;
+        }
+      }
+    }
+  }
+  for (j=act;j;j--) // renumber m_act
+  {
+    k = 1;
+    a = m_act[j];
+    while ((a != NULL) && (a->pos <= tored))
+    {
+      if (perm[crd+k] == a->pos)
+      {
+        a->pos = crd+k;
+        a = a->n;
+      }
+      k++;
+    }
+  }
+  tored = crd+i;
+  for(k=1;k<=i;k++) // clean this from m_row
+  {
+    j = perm[crd+k];
+    if (m_row[j] != NULL)
+    {
+      r = m_row[j];
+      m_row[j] = NULL;
+      do
+      {
+        ap = m_res[r->pos];
+        loop
+        {
+          a = ap->n;
+          if (a == NULL)
+          {
+            h = ap->n = r;
+            r = r->n;
+            h->n = NULL;
+            h->pos = crd+k;
+            break;
+          }
+          ap = a;
+        }
+      } while (r!=NULL);
+    }
+  }
+  while(act) // clean m_act
+  {
+    crd++;
+    m_res[crd] = m_act[act];
+    act--;
+  }
+  for (i=1;i<=tored;i++) // take the rest of m_row
+  {
+    if(m_row[i] != NULL)
+    {
+      tored++;
+      r = m_row[i];
+      m_row[i] = NULL;
+      perm[tored] = i;
+      do
+      {
+        ap = m_res[r->pos];
+        loop
+        {
+          a = ap->n;
+          if (a == NULL)
+          {
+            h = ap->n = r;
+            r = r->n;
+            h->n = NULL;
+            h->pos = tored;
+            break;
+          }
+          ap = a;
+        }
+      } while (r!=NULL);
+    }
+  }
+  for (i=tored+1;i<=nrows;i++) // take the rest of m_row
+  {
+    if(m_row[i] != NULL)
+    {
+      r = m_row[i];
+      m_row[i] = NULL;
+      do
+      {
+        ap = m_res[r->pos];
+        loop
+        {
+          a = ap->n;
+          if (a == NULL)
+          {
+            h = ap->n = r;
+            r = r->n;
+            h->n = NULL;
+            h->pos = i;
+            break;
+          }
+          ap = a;
+        }
+      } while (r!=NULL);
+    }
+  }
+  while (inred < ncols) // take unreducable
+  {
+    crd++;
+    inred++;
+    m_res[crd] = m_res[inred];
+  }
+}
+
+/*
+* multiply and divide the column, that goes to result
+*/
+void sparse_mat::smMultCol()
+{
+  smpoly a = m_act[act];
+  int e = crd;
+  poly ha;
+  int f;
+
+  while (a != NULL)
+  {
+    f = a->e;
+    if (f < e)
+    {
+      ha = SM_MULT(a->m, m_res[e]->m, m_res[f]->m);
+      pDelete(&a->m);
+      if (f) SM_DIV(ha, m_res[f]->m);
+      a->m = ha;
+      if (normalize) pNormalize(a->m);
+    }
+    a = a->n;
+  }
+}
+
+/*
+* multiply and divide the m_act finaly
+*/
+void sparse_mat::smFinalMult()
+{
+  smpoly a;
+  poly ha;
+  int i, f;
+  int e = crd;
+
+  for (i=act; i; i--)
+  {
+    a = m_act[i];
+    do
+    {
+      f = a->e;
+      if (f < e)
+      {
+        ha = SM_MULT(a->m, m_res[e]->m, m_res[f]->m);
+        pDelete(&a->m);
+        if (f) SM_DIV(ha, m_res[f]->m);
+        a->m = ha;
+      }
+      if (normalize) pNormalize(a->m);
+      a = a->n;
+    } while (a != NULL);
+  }
+}
+
+/*
+* check for denominators
+*/
+int sparse_mat::smCheckNormalize()
+{
+  int i;
+  smpoly a;
+
+  for (i=act; i; i--)
+  {
+    a = m_act[i];
+    do
+    {
+      if(smHaveDenom(a->m)) return 1;
+      a = a->n;
+    } while (a != NULL);
+  }
+  return 0;
+}
+
+/*
+* normalize
+*/
+void sparse_mat::smNormalize()
+{
+  smpoly a;
+  int i;
+  int e = crd;
+
+  for (i=act; i; i--)
+  {
+    a = m_act[i];
+    do
+    {
+      if (e == a->e) pNormalize(a->m);
+      a = a->n;
+    } while (a != NULL);
+  }
+}
+
+/*
+* multiply and divide the element, save poly
+*/
+poly sparse_mat::smMultPoly(smpoly a)
+{
+  int f = a->e;
+  poly r, h;
+
+  if (f < crd)
+  {
+    h = r = a->m;
+    h = SM_MULT(h, m_res[crd]->m, m_res[f]->m);
+    if (f) SM_DIV(h, m_res[f]->m);
+    a->m = h;
+    if (normalize) pNormalize(a->m);
+    a->f = smPolyWeight(a);
+    return r;
+  }
+  else
+    return NULL;
+}
+
+/*
+* delete the m_act finaly
+*/
+void sparse_mat::smActDel()
+{
+  smpoly a;
+  int i;
+
+  for (i=act; i; i--)
+  {
+    a = m_act[i];
+    do
+    {
+      smElemDelete(&a);
+    } while (a != NULL);
+  }
+}
+
+/*
+* delete the pivotcol
+*/
+void sparse_mat::smColDel()
+{
+  smpoly a = m_act[act];
+
+  while (a != NULL)
+  {
+    smElemDelete(&a);
+  }
+}
+
+/*
+* delete pivot elements
+*/
+void sparse_mat::smPivDel()
+{
+  int i=crd;
+
+  while (i != 0)
+  {
+    smElemDelete(&m_res[i]);
+    i--;
+  }
+}
+
+/*
+* the sign of the determinant
+*/
+void sparse_mat::smSign()
+{
+  int j,i;
+  if (act > 2)
+  {
+    if (cpiv!=act) sign=-sign;
+    if ((act%2)==0) sign=-sign;
+    i=1;
+    j=perm[1];
+    while(j<rpiv)
+    {
+      sign=-sign;
+      i++;
+      j=perm[i];
+    }
+    while(perm[i]!=0)
+    {
+      perm[i]=perm[i+1];
+      i++;
+    }
+  }
+  else
+  {
+    if (cpiv!=1) sign=-sign;
+    if (rpiv!=perm[1]) sign=-sign;
+  }
+}
+
+void sparse_mat::smInitPerm()
+{
+  int i;
+  for (i=act;i;i--) perm[i]=i;
+}
+
+/* ----------------- arithmetic ------------------ */
+/*2
+* exact division a/b
+* a destroyed, b NOT destroyed
+*/
+void smPolyDiv(poly a, poly b)
+{
+  const number x = pGetCoeff(b);
+  number y, yn;
+  poly t, h, dummy;
+  int i;
+
+  if (pNext(b) == NULL)
+  {
+    do
+    {
+      if (!pLmIsConstantComp(b))
+      {
+        for (i=pVariables; i; i--)
+          pSubExp(a,i,pGetExp(b,i));
+        pSetm(a);
+      }
+      y = nDiv(pGetCoeff(a),x);
+      nNormalize(y);
+      pSetCoeff(a,y);
+      pIter(a);
+    } while (a != NULL);
+    return;
+  }
+  dummy = pInit();
+  do
+  {
+    for (i=pVariables; i; i--)
+      pSubExp(a,i,pGetExp(b,i));
+    pSetm(a);
+    y = nDiv(pGetCoeff(a),x);
+    nNormalize(y);
+    pSetCoeff(a,y);
+    yn = nNeg(nCopy(y));
+    t = pNext(b);
+    h = dummy;
+    do
+    {
+      h = pNext(h) = pInit();
+      //pSetComp(h,0);
+      for (i=pVariables; i; i--)
+        pSetExp(h,i,pGetExp(a,i)+pGetExp(t,i));
+      pSetm(h);
+      pSetCoeff0(h,nMult(yn, pGetCoeff(t)));
+      pIter(t);
+    } while (t != NULL);
+    nDelete(&yn);
+    pNext(h) = NULL;
+    a = pNext(a) = pAdd(pNext(a), pNext(dummy));
+  } while (a!=NULL);
+  pLmFree(dummy);
+}
+
+#define X_MAS
+#ifdef X_MAS
+
+/*
+*  returns the part of (a*b)/exp(lead(c)) with nonegative exponents
+*/
+poly smMultDiv(poly a, poly b, const poly c)
+{
+  poly pa, e, res, r;
+  BOOLEAN lead;\
+  int la, lb, lr;
+
+  if ((c == NULL) || pLmIsConstantComp(c))
+  {
+    return ppMult_qq(a, b);
+  }
+
+  pqLength(a, b, la, lb, SM_MIN_LENGTH_BUCKET);
+
+  // we iter over b, so, make sure b is the shortest
+  // such that we minimize our iterations
+  if (lb > la)
+  {
+    r = a;
+    a = b;
+    b = r;
+    lr = la;
+    la = lb;
+    lb = lr;
+  }
+  res = NULL;
+  e = pInit();
+  lead = FALSE;
+  while (!lead)
+  {
+    pSetCoeff0(e,pGetCoeff(b));
+    if (smIsNegQuot(e, b, c))
+    {
+      lead = pLmDivisibleByNoComp(e, a);
+      r = smSelectCopy_ExpMultDiv(a, e, b, c);
+    }
+    else
+    {
+      lead = TRUE;
+      r = ppMult_mm(a, e);
+    }
+    if (lead)
+    {
+      if (res != NULL)
+      {
+        smFindRef(&pa, &res, r);
+        if (pa == NULL)
+          lead = FALSE;
+      }
+      else
+      {
+        pa = res = r;
+      }
+    }
+    else
+      res = pAdd(res, r);
+    pIter(b);
+    if (b == NULL)
+    {
+      pLmFree(e);
+      return res;
+    }
+  }
+
+  if (!TEST_OPT_NOT_BUCKETS && lb >= SM_MIN_LENGTH_BUCKET)
+  {
+    // use buckets if minimum length is smaller than threshold
+    spolyrec rp;
+    poly append;
+    // find the last monomial before pa
+    if (res == pa)
+    {
+      append = &rp;
+      pNext(append) = res;
+    }
+    else
+    {
+      append = res;
+      while (pNext(append) != pa)
+      {
+        assume(pNext(append) != NULL);
+        pIter(append);
+      }
+    }
+    kBucket_pt bucket = kBucketCreate(currRing);
+    kBucketInit(bucket, pNext(append), 0);
+    do
+    {
+      pSetCoeff0(e,pGetCoeff(b));
+      if (smIsNegQuot(e, b, c))
+      {
+        lr = la;
+        r = pp_Mult_Coeff_mm_DivSelect_MultDiv(a, lr, e, b, c);
+        if (pLmDivisibleByNoComp(e, a))
+          append = kBucket_ExtractLarger_Add_q(bucket, append, r, &lr);
+        else
+          kBucket_Add_q(bucket, r, &lr);
+      }
+      else
+      {
+        r = ppMult_mm(a, e);
+        append = kBucket_ExtractLarger_Add_q(bucket, append, r, &la);
+      }
+      pIter(b);
+    } while (b != NULL);
+    pNext(append) = kBucketClear(bucket);
+    kBucketDestroy(&bucket);
+  }
+  else
+  {
+    // use old sm stuff
+    do
+    {
+      pSetCoeff0(e,pGetCoeff(b));
+      if (smIsNegQuot(e, b, c))
+      {
+        r = smSelectCopy_ExpMultDiv(a, e, b, c);
+        if (pLmDivisibleByNoComp(e, a))
+          smCombineChain(&pa, r);
+        else
+          pa = pAdd(pa,r);
+      }
+      else
+      {
+        r = ppMult_mm(a, e);
+        smCombineChain(&pa, r);
+      }
+      pIter(b);
+    } while (b != NULL);
+  }
+  pLmFree(e);
+  return res;
+}
+
+#else
+
+/*
+*  returns the part of (a*b)/exp(lead(c)) with nonegative exponents
+*/
+poly smMultDiv(poly a, poly b, const poly c)
+{
+  poly pa, e, res, r;
+  BOOLEAN lead;
+
+  if ((c == NULL) || pLmIsConstantComp(c))
+  {
+    return ppMult_qq(a, b);
+  }
+  if (smSmaller(a, b))
+  {
+    r = a;
+    a = b;
+    b = r;
+  }
+  res = NULL;
+  e = pInit();
+  lead = FALSE;
+  while (!lead)
+  {
+    pSetCoeff0(e,pGetCoeff(b));
+    if (smIsNegQuot(e, b, c))
+    {
+      lead = pLmDivisibleByNoComp(e, a);
+      r = smSelectCopy_ExpMultDiv(a, e, b, c);
+    }
+    else
+    {
+      lead = TRUE;
+      r = ppMult_mm(a, e);
+    }
+    if (lead)
+    {
+      if (res != NULL)
+      {
+        smFindRef(&pa, &res, r);
+        if (pa == NULL)
+          lead = FALSE;
+      }
+      else
+      {
+        pa = res = r;
+      }
+    }
+    else
+      res = pAdd(res, r);
+    pIter(b);
+    if (b == NULL)
+    {
+      pLmFree(e);
+      return res;
+    }
+  }
+  do
+  {
+    pSetCoeff0(e,pGetCoeff(b));
+    if (smIsNegQuot(e, b, c))
+    {
+      r = smSelectCopy_ExpMultDiv(a, e, b, c);
+      if (pLmDivisibleByNoComp(e, a))
+        smCombineChain(&pa, r);
+      else
+        pa = pAdd(pa,r);
+    }
+    else
+    {
+      r = ppMult_mm(a, e);
+      smCombineChain(&pa, r);
+    }
+    pIter(b);
+  } while (b != NULL);
+  pLmFree(e);
+  return res;
+}
+#endif
+/*n
+* exact division a/b
+* a is a result of smMultDiv
+* a destroyed, b NOT destroyed
+*/
+void smSpecialPolyDiv(poly a, poly b)
+{
+  if (pNext(b) == NULL)
+  {
+    smPolyDivN(a, pGetCoeff(b));
+    return;
+  }
+  smExactPolyDiv(a, b);
+}
+
+
+/* ------------ internals arithmetic ------------- */
+static void smExactPolyDiv(poly a, poly b)
+{
+  const number x = pGetCoeff(b);
+  poly tail = pNext(b), e = pInit();
+  poly h;
+  number y, yn;
+  int lt = pLength(tail);
+
+  if (lt + 1 >= SM_MIN_LENGTH_BUCKET &&  !TEST_OPT_NOT_BUCKETS)
+  {
+    kBucket_pt bucket = kBucketCreate(currRing);
+    kBucketInit(bucket, pNext(a), 0);
+    int lh = 0;
+    do
+    {
+      y = nDiv(pGetCoeff(a), x);
+      nNormalize(y);
+      pSetCoeff(a,y);
+      yn = nNeg(nCopy(y));
+      pSetCoeff0(e,yn);
+      lh = lt;
+      if (smIsNegQuot(e, a, b))
+      {
+        h = pp_Mult_Coeff_mm_DivSelect_MultDiv(tail, lh, e, a, b);
+      }
+      else
+        h = ppMult_mm(tail, e);
+      nDelete(&yn);
+      kBucket_Add_q(bucket, h, &lh);
+
+      a = pNext(a) = kBucketExtractLm(bucket);
+    } while (a!=NULL);
+    kBucketDestroy(&bucket);
+  }
+  else
+  {
+    do
+    {
+      y = nDiv(pGetCoeff(a), x);
+      nNormalize(y);
+      pSetCoeff(a,y);
+      yn = nNeg(nCopy(y));
+      pSetCoeff0(e,yn);
+      if (smIsNegQuot(e, a, b))
+        h = smSelectCopy_ExpMultDiv(tail, e, a, b);
+      else
+        h = ppMult_mm(tail, e);
+      nDelete(&yn);
+      a = pNext(a) = pAdd(pNext(a), h);
+    } while (a!=NULL);
+  }
+  pLmFree(e);
+}
+
+// obachman --> Wilfried: check the following
+static BOOLEAN smIsNegQuot(poly a, const poly b, const poly c)
+{
+  if (pLmDivisibleByNoComp(c, b))
+  {
+    pExpVectorDiff(a, b, c);
+    // Hmm: here used to be a pSetm(a): but it is unnecessary,
+    // if b and c are correct
+    return FALSE;
+  }
+  else
+  {
+    int i;
+    for (i=pVariables; i>0; i--)
+    {
+      if(pGetExp(c,i) > pGetExp(b,i))
+        pSetExp(a,i,pGetExp(c,i)-pGetExp(b,i));
+      else
+        pSetExp(a,i,0);
+    }
+    // here we actually might need a pSetm, if a is to be used in
+    // comparisons
+    return TRUE;
+  }
+}
+
+static void smExpMultDiv(poly t, const poly b, const poly c)
+{
+  int i;
+  pTest(t);
+  pLmTest(b);
+  pLmTest(c);
+  poly bc = p_New(currRing);
+
+  p_ExpVectorDiff(bc, b, c, currRing);
+
+  while(t!=NULL)
+  {
+    pExpVectorAdd(t, bc);
+    pIter(t);
+  }
+  p_LmFree(bc, currRing);
+}
+
+
+static void smPolyDivN(poly a, const number x)
+{
+  number y;
+
+  do
+  {
+    y = nDiv(pGetCoeff(a),x);
+    nNormalize(y);
+    pSetCoeff(a,y);
+    pIter(a);
+  } while (a != NULL);
+}
+
+static BOOLEAN smSmaller(poly a, poly b)
+{
+  loop
+  {
+    pIter(b);
+    if (b == NULL) return TRUE;
+    pIter(a);
+    if (a == NULL) return FALSE;
+  }
+}
+
+static void smCombineChain(poly *px, poly r)
+{
+  poly pa = *px, pb;
+  number x;
+  int i;
+
+  loop
+  {
+    pb = pNext(pa);
+    if (pb == NULL)
+    {
+      pa = pNext(pa) = r;
+      break;
+    }
+    i = pLmCmp(pb, r);
+    if (i > 0)
+      pa = pb;
+    else
+    {
+      if (i == 0)
+      {
+        x = nAdd(pGetCoeff(pb), pGetCoeff(r));
+        pDeleteLm(&r);
+        if (nIsZero(x))
+        {
+          pDeleteLm(&pb);
+          pNext(pa) = pAdd(pb,r);
+        }
+        else
+        {
+          pa = pb;
+          pSetCoeff(pa,x);
+          pNext(pa) = pAdd(pNext(pa), r);
+        }
+      }
+      else
+      {
+        pa = pNext(pa) = r;
+        pNext(pa) = pAdd(pb, pNext(pa));
+      }
+      break;
+    }
+  }
+  *px = pa;
+}
+
+
+static void smFindRef(poly *ref, poly *px, poly r)
+{
+  number x;
+  int i;
+  poly pa = *px, pp = NULL;
+
+  loop
+  {
+    i = pLmCmp(pa, r);
+    if (i > 0)
+    {
+      pp = pa;
+      pIter(pa);
+      if (pa==NULL)
+      {
+        pNext(pp) = r;
+        break;
+      }
+    }
+    else
+    {
+      if (i == 0)
+      {
+        x = nAdd(pGetCoeff(pa), pGetCoeff(r));
+        pDeleteLm(&r);
+        if (nIsZero(x))
+        {
+          pDeleteLm(&pa);
+          if (pp!=NULL)
+            pNext(pp) = pAdd(pa,r);
+          else
+            *px = pAdd(pa,r);
+        }
+        else
+        {
+          pp = pa;
+          pSetCoeff(pp,x);
+          pNext(pp) = pAdd(pNext(pp), r);
+        }
+      }
+      else
+      {
+        if (pp!=NULL)
+          pp = pNext(pp) = r;
+        else
+          *px = pp = r;
+        pNext(pp) = pAdd(pa, pNext(r));
+      }
+      break;
+    }
+  }
+  *ref = pp;
+}
+
+/* ----------------- internal 'C' stuff ------------------ */
+
+static void smElemDelete(smpoly *r)
+{
+  smpoly a = *r, b = a->n;
+
+  pDelete(&a->m);
+  omFreeBin((void *)a,  smprec_bin);
+  *r = b;
+}
+
+static smpoly smElemCopy(smpoly a)
+{
+  smpoly r = (smpoly)omAllocBin(smprec_bin);
+  memcpy(r, a, sizeof(smprec));
+/*  r->m = pCopy(r->m); */
+  return r;
+}
+
+/*
+* from poly to smpoly
+* do not destroy p
+*/
+static smpoly smPoly2Smpoly(poly q)
+{
+  poly pp;
+  smpoly res, a;
+  Exponent_t x;
+
+  if (q == NULL)
+    return NULL;
+  a = res = (smpoly)omAllocBin(smprec_bin);
+  a->pos = x = pGetComp(q);
+  a->m = q;
+  a->e = 0;
+  loop
+  {
+    pSetComp(q,0);
+    pp = q;
+    pIter(q);
+    if (q == NULL)
+    {
+      a->n = NULL;
+      return res;
+    }
+    if (pGetComp(q) != x)
+    {
+      a = a->n = (smpoly)omAllocBin(smprec_bin);
+      pNext(pp) = NULL;
+      a->pos = x = pGetComp(q);
+      a->m = q;
+      a->e = 0;
+    }
+  }
+}
+
+/*
+* from smpoly to poly
+* destroy a
+*/
+static poly smSmpoly2Poly(smpoly a)
+{
+  smpoly b;
+  poly res, pp, q;
+  Exponent_t x;
+
+  if (a == NULL)
+    return NULL;
+  x = a->pos;
+  q = res = a->m;
+  loop
+  {
+    pSetComp(q,x);
+    pp = q;
+    pIter(q);
+    if (q == NULL)
+      break;
+  }
+  loop
+  {
+    b = a;
+    a = a->n;
+    omFreeBin((void *)b,  smprec_bin);
+    if (a == NULL)
+      return res;
+    x = a->pos;
+    q = pNext(pp) = a->m;
+    loop
+    {
+      pSetComp(q,x);
+      pp = q;
+      pIter(q);
+      if (q == NULL)
+        break;
+    }
+  }
+}
+
+/*
+* weigth of a polynomial, for pivot strategy
+*/
+static float smPolyWeight(smpoly a)
+{
+  poly p = a->m;
+  int i;
+  float res = (float)nSize(pGetCoeff(p));
+
+  if (pNext(p) == NULL)
+  {
+    for(i=pVariables; i>0; i--)
+    {
+      if (pGetExp(p,i) != 0) return res+1.0;
+    }
+    return res;
+  }
+  else
+  {
+    i = 0;
+    res = 0.0;
+    do
+    {
+      i++;
+      res += (float)nSize(pGetCoeff(p));
+      pIter(p);
+    }
+    while (p);
+    return res+(float)i;
+  }
+}
+
+static BOOLEAN smHaveDenom(poly a)
+{
+  BOOLEAN sw;
+  number x,o=nInit(1);
+
+  while (a != NULL)
+  {
+    x = nGetDenom(pGetCoeff(a));
+    sw = nEqual(x,o);
+    nDelete(&x);
+    if (!sw)
+    {
+      nDelete(&o);
+      return TRUE;
+    }
+    pIter(a);
+  }
+  nDelete(&o);
+  return FALSE;
+}
+
+static number smCleardenom(ideal id)
+{
+  poly a;
+  number x,y,res=nInit(1);
+  BOOLEAN sw=FALSE;
+
+  for (int i=0; i<IDELEMS(id); i++)
+  {
+    a = id->m[i];
+    sw = smHaveDenom(a);
+    if (sw) break;
+  }
+  if (!sw) return res;
+  for (int i=0; i<IDELEMS(id); i++)
+  {
+    a = id->m[i];
+    if (a!=NULL)
+    {
+      x = nCopy(pGetCoeff(a));
+      pCleardenom(a);
+      y = nDiv(x,pGetCoeff(a));
+      nDelete(&x);
+      x = nMult(res,y);
+      nNormalize(x);
+      nDelete(&res);
+      res = x;
+    }
+  }
+  return res;
+}
+
+/* ----------------- gauss elimination ------------------ */
+/* in structs.h */
+typedef struct smnrec sm_nrec;
+typedef sm_nrec * smnumber;
+struct smnrec{
+  smnumber n;          // the next element
+  int pos;             // position
+  number m;            // the element
+};
+
+static omBin smnrec_bin = omGetSpecBin(sizeof(smnrec));
+
+/* declare internal 'C' stuff */
+static void smNumberDelete(smnumber *);
+static smnumber smNumberCopy(smnumber);
+static smnumber smPoly2Smnumber(poly);
+static poly smSmnumber2Poly(number);
+static BOOLEAN smCheckSolv(ideal);
+
+/* class for sparse number matrix:
+*/
+class sparse_number_mat{
+private:
+  int nrows, ncols;    // dimension of the problem
+  int act;             // number of unreduced columns (start: ncols)
+  int crd;             // number of reduced columns (start: 0)
+  int tored;           // border for rows to reduce
+  int sing;            // indicator for singular problem
+  int rpiv;            // row-position of the pivot
+  int *perm;           // permutation of rows
+  number one;          // the "1"
+  number *sol;         // field for solution
+  int *wrw, *wcl;      // weights of rows and columns
+  smnumber * m_act;    // unreduced columns
+  smnumber * m_res;    // reduced columns (result)
+  smnumber * m_row;    // reduced part of rows
+  smnumber red;        // row to reduce
+  smnumber piv;        // pivot
+  smnumber dumm;       // allocated dummy
+  void smColToRow();
+  void smRowToCol();
+  void smSelectPR();
+  void smRealPivot();
+  void smZeroToredElim();
+  void smGElim();
+  void smAllDel();
+public:
+  sparse_number_mat(ideal);
+  ~sparse_number_mat();
+  int smIsSing() { return sing; }
+  void smTriangular();
+  void smSolv();
+  ideal smRes2Ideal();
+};
+
+/* ----------------- basics (used from 'C') ------------------ */
+/*2
+* returns the solution of a linear equation
+* solution of M*x = r (M has dimension nXn) =>
+*   I = module(transprose(M)) + r*gen(n+1)
+* uses  Gauss-elimination
+*/
+ideal smCallSolv(ideal I)
+{
+  sparse_number_mat *linsolv;
+  ring origR;
+  sip_sring tmpR;
+  ideal rr;
+
+  if (idIsConstant(I)==FALSE)
+  {
+    WerrorS("symbol in equation");
+    return NULL;
+  }
+  I->rank = idRankFreeModule(I);
+  if (smCheckSolv(I)) return NULL;
+  smRingChange(&origR,tmpR,1);
+  rr=idrCopyR(I,origR);
+  linsolv = new sparse_number_mat(rr);
+  rr=NULL;
+  linsolv->smTriangular();
+  if (linsolv->smIsSing() == 0)
+  {
+    linsolv->smSolv();
+    rr = linsolv->smRes2Ideal();
+  }
+  else
+    WerrorS("singular problem for linsolv");
+  delete linsolv;
+  rChangeCurrRing(origR);
+  if (rr!=NULL)
+    rr = idrMoveR(rr,&tmpR);
+  smRingClean(origR,tmpR);
+  return rr;
+}
+
+/*
+* constructor, destroy smat
+*/
+sparse_number_mat::sparse_number_mat(ideal smat)
+{
+  int i;
+  polyset pmat;
+
+  crd = sing = 0;
+  act = ncols = smat->ncols;
+  tored = nrows = smat->rank;
+  i = tored+1;
+  perm = (int *)omAlloc(sizeof(int)*i);
+  m_row = (smnumber *)omAlloc0(sizeof(smnumber)*i);
+  wrw = (int *)omAlloc(sizeof(int)*i);
+  i = ncols+1;
+  wcl = (int *)omAlloc(sizeof(int)*i);
+  m_act = (smnumber *)omAlloc(sizeof(smnumber)*i);
+  m_res = (smnumber *)omAlloc0(sizeof(smnumber)*i);
+  dumm = (smnumber)omAllocBin(smnrec_bin);
+  pmat = smat->m;
+  for(i=ncols; i; i--)
+  {
+    m_act[i] = smPoly2Smnumber(pmat[i-1]);
+  }
+  omFreeSize((ADDRESS)pmat,smat->ncols*sizeof(poly));
+  omFreeBin((ADDRESS)smat, sip_sideal_bin);
+  one = nInit(1);
+}
+
+/*
+* destructor
+*/
+sparse_number_mat::~sparse_number_mat()
+{
+  int i;
+  omFreeBin((ADDRESS)dumm,  smnrec_bin);
+  i = ncols+1;
+  omFreeSize((ADDRESS)m_res, sizeof(smnumber)*i);
+  omFreeSize((ADDRESS)m_act, sizeof(smnumber)*i);
+  omFreeSize((ADDRESS)wcl, sizeof(int)*i);
+  i = nrows+1;
+  omFreeSize((ADDRESS)wrw, sizeof(int)*i);
+  omFreeSize((ADDRESS)m_row, sizeof(smnumber)*i);
+  omFreeSize((ADDRESS)perm, sizeof(int)*i);
+  nDelete(&one);
+}
+
+/*
+* triangularization by Gauss-elimination
+*/
+void sparse_number_mat::smTriangular()
+{
+  tored--;
+  this->smZeroToredElim();
+  if (sing != 0) return;
+  while (act > 1)
+  {
+    this->smRealPivot();
+    this->smSelectPR();
+    this->smGElim();
+    crd++;
+    this->smColToRow();
+    act--;
+    this->smRowToCol();
+    this->smZeroToredElim();
+    if (sing != 0) return;
+  }
+  if (TEST_OPT_PROT) PrintS(".\n");
+  piv = m_act[1];
+  rpiv = piv->pos;
+  m_act[1] = piv->n;
+  piv->n = NULL;
+  crd++;
+  this->smColToRow();
+  act--;
+  this->smRowToCol();
+}
+
+/*
+* solve the triangular system
+*/
+void sparse_number_mat::smSolv()
+{
+  int i, j;
+  number x, y, z;
+  smnumber s, d, r = m_row[nrows];
+
+  m_row[nrows] = NULL;
+  sol = (number *)omAlloc0(sizeof(number)*(crd+1));
+  while (r != NULL)  // expand the rigth hand side
+  {
+    sol[r->pos] = r->m;
+    s = r;
+    r = r->n;
+    omFreeBin((ADDRESS)s,  smnrec_bin);
+  }
+  i = crd;  // solve triangular system
+  if (sol[i] != NULL)
+  {
+    x = sol[i];
+    sol[i] = nDiv(x, m_res[i]->m);
+    nDelete(&x);
+  }
+  i--;
+  while (i > 0)
+  {
+    x = NULL;
+    d = m_res[i];
+    s = d->n;
+    while (s != NULL)
+    {
+      j = s->pos;
+      if (sol[j] != NULL)
+      {
+        z = nMult(sol[j], s->m);
+        if (x != NULL)
+        {
+          y = x;
+          x = nSub(y, z);
+          nDelete(&y);
+          nDelete(&z);
+        }
+        else
+          x = nNeg(z);
+      }
+      s = s->n;
+    }
+    if (sol[i] != NULL)
+    {
+      if (x != NULL)
+      {
+        y = nAdd(x, sol[i]);
+        nDelete(&x);
+        if (nIsZero(y))
+        {
+          nDelete(&sol[i]);
+          sol[i] = NULL;
+        }
+        else
+          sol[i] = y;
+      }
+    }
+    else
+      sol[i] = x;
+    if (sol[i] != NULL)
+    {
+      x = sol[i];
+      sol[i] = nDiv(x, d->m);
+      nDelete(&x);
+    }
+    i--;
+  }
+  this->smAllDel();
+}
+
+/*
+* transform the result to an ideal
+*/
+ideal sparse_number_mat::smRes2Ideal()
+{
+  int i, j;
+  ideal res = idInit(crd, 1);
+
+  for (i=crd; i; i--)
+  {
+    j = perm[i]-1;
+    res->m[j] = smSmnumber2Poly(sol[i]);
+  }
+  omFreeSize((ADDRESS)sol, sizeof(number)*(crd+1));
+  return res;
+}
+
+/* ----------------- pivot method ------------------ */
+
+/*
+* compute pivot
+*/
+void sparse_number_mat::smRealPivot()
+{
+  smnumber a;
+  number x, xo;
+  int i, copt, ropt;
+
+  xo=nInit(0);
+  for (i=act; i; i--)
+  {
+    a = m_act[i];
+    while ((a!=NULL) && (a->pos<=tored))
+    {
+      x = a->m;
+      if (nGreaterZero(x))
+      {
+        if (nGreater(x,xo))
+        {
+          nDelete(&xo);
+          xo = nCopy(x);
+          copt = i;
+          ropt = a->pos;
+        }
+      }
+      else
+      {
+        xo = nNeg(xo);
+        if (nGreater(xo,x))
+        {
+          nDelete(&xo);
+          xo = nCopy(x);
+          copt = i;
+          ropt = a->pos;
+        }
+        xo = nNeg(xo);
+      }
+      a = a->n;
+    }
+  }
+  rpiv = ropt;
+  if (copt != act)
+  {
+    a = m_act[act];
+    m_act[act] = m_act[copt];
+    m_act[copt] = a;
+  }
+  nDelete(&xo);
+}
+
+/* ----------------- elimination ------------------ */
+
+/* one step of Gauss-elimination */
+void sparse_number_mat::smGElim()
+{
+  number p = nDiv(one,piv->m);  // pivotelement
+  smnumber c = m_act[act];      // pivotcolumn
+  smnumber r = red;             // row to reduce
+  smnumber res, a, b;
+  number w, ha, hb;
+
+  if ((c == NULL) || (r == NULL))
+  {
+    while (r!=NULL) smNumberDelete(&r);
+    return;
+  }
+  do
+  {
+    a = m_act[r->pos];
+    res = dumm;
+    res->n = NULL;
+    b = c;
+    w = nMult(r->m, p);
+    nDelete(&r->m);
+    r->m = w;
+    loop   // combine the chains a and b: a + w*b
+    {
+      if (a == NULL)
+      {
+        do
+        {
+          res = res->n = smNumberCopy(b);
+          res->m = nMult(b->m, w);
+          b = b->n;
+        } while (b != NULL);
+        break;
+      }
+      if (a->pos < b->pos)
+      {
+        res = res->n = a;
+        a = a->n;
+      }
+      else if (a->pos > b->pos)
+      {
+        res = res->n = smNumberCopy(b);
+        res->m = nMult(b->m, w);
+        b = b->n;
+      }
+      else
+      {
+        hb = nMult(b->m, w);
+        ha = nAdd(a->m, hb);
+        nDelete(&hb);
+        nDelete(&a->m);
+        if (nIsZero(ha))
+        {
+          smNumberDelete(&a);
+        }
+        else
+        {
+          a->m = ha;
+          res = res->n = a;
+          a = a->n;
+        }
+        b = b->n;
+      }
+      if (b == NULL)
+      {
+        res->n = a;
+        break;
+      }
+    }
+    m_act[r->pos] = dumm->n;
+    smNumberDelete(&r);
+  } while (r != NULL);
+  nDelete(&p);
+}
+
+/* ----------------- transfer ------------------ */
+
+/*
+* select the pivotrow and store it to red and piv
+*/
+void sparse_number_mat::smSelectPR()
+{
+  smnumber b = dumm;
+  smnumber a, ap;
+  int i;
+
+  if (TEST_OPT_PROT)
+  {
+    if ((crd+1)%10)
+      PrintS(".");
+    else
+      PrintS(".\n");
+  }
+  a = m_act[act];
+  if (a->pos < rpiv)
+  {
+    do
+    {
+      ap = a;
+      a = a->n;
+    } while (a->pos < rpiv);
+    ap->n = a->n;
+  }
+  else
+    m_act[act] = a->n;
+  piv = a;
+  a->n = NULL;
+  for (i=1; i<act; i++)
+  {
+    a = m_act[i];
+    if (a->pos < rpiv)
+    {
+      loop
+      {
+        ap = a;
+        a = a->n;
+        if ((a == NULL) || (a->pos > rpiv))
+          break;
+        if (a->pos == rpiv)
+        {
+          ap->n = a->n;
+          a->m = nNeg(a->m);
+          b = b->n = a;
+          b->pos = i;
+          break;
+        }
+      }
+    }
+    else if (a->pos == rpiv)
+    {
+      m_act[i] = a->n;
+      a->m = nNeg(a->m);
+      b = b->n = a;
+      b->pos = i;
+    }
+  }
+  b->n = NULL;
+  red = dumm->n;
+}
+
+/*
+* store the pivotcol in m_row
+*   m_act[cols][pos(rows)] => m_row[rows][pos(cols)]
+*/
+void sparse_number_mat::smColToRow()
+{
+  smnumber c = m_act[act];
+  smnumber h;
+
+  while (c != NULL)
+  {
+    h = c;
+    c = c->n;
+    h->n = m_row[h->pos];
+    m_row[h->pos] = h;
+    h->pos = crd;
+  }
+}
+
+/*
+* store the pivot and the assosiated row in m_row
+* to m_res (result):
+*   piv + m_row[rows][pos(cols)] => m_res[cols][pos(rows)]
+*/
+void sparse_number_mat::smRowToCol()
+{
+  smnumber r = m_row[rpiv];
+  smnumber a, ap, h;
+
+  m_row[rpiv] = NULL;
+  perm[crd] = rpiv;
+  piv->pos = crd;
+  m_res[crd] = piv;
+  while (r != NULL)
+  {
+    ap = m_res[r->pos];
+    loop
+    {
+      a = ap->n;
+      if (a == NULL)
+      {
+        ap->n = h = r;
+        r = r->n;
+        h->n = a;
+        h->pos = crd;
+        break;
+      }
+      ap = a;
+    }
+  }
+}
+
+/* ----------------- C++ stuff ------------------ */
+
+/*
+*  check singularity
+*/
+void sparse_number_mat::smZeroToredElim()
+{
+  smnumber a;
+  int i = act;
+
+  loop
+  {
+    if (i == 0) return;
+    a = m_act[i];
+    if ((a==NULL) || (a->pos>tored))
+    {
+      sing = 1;
+      this->smAllDel();
+      return;
+    }
+    i--;
+  }
+}
+
+/*
+* delete all smnumber's
+*/
+void sparse_number_mat::smAllDel()
+{
+  smnumber a;
+  int i;
+
+  for (i=act; i; i--)
+  {
+    a = m_act[i];
+    while (a != NULL)
+      smNumberDelete(&a);
+  }
+  for (i=crd; i; i--)
+  {
+    a = m_res[i];
+    while (a != NULL)
+      smNumberDelete(&a);
+  }
+  if (act)
+  {
+    for (i=nrows; i; i--)
+    {
+      a = m_row[i];
+      while (a != NULL)
+        smNumberDelete(&a);
+    }
+  }
+}
+
+/* ----------------- internal 'C' stuff ------------------ */
+
+static void smNumberDelete(smnumber *r)
+{
+  smnumber a = *r, b = a->n;
+
+  nDelete(&a->m);
+  omFreeBin((ADDRESS)a,  smnrec_bin);
+  *r = b;
+}
+
+static smnumber smNumberCopy(smnumber a)
+{
+  smnumber r = (smnumber)omAllocBin(smnrec_bin);
+  memcpy(r, a, sizeof(smnrec));
+  return r;
+}
+
+/*
+* from poly to smnumber
+* do not destroy p
+*/
+static smnumber smPoly2Smnumber(poly q)
+{
+  smnumber a, res;
+  poly p = q;
+
+  if (p == NULL)
+    return NULL;
+  a = res = (smnumber)omAllocBin(smnrec_bin);
+  a->pos = pGetComp(p);
+  a->m = pGetCoeff(p);
+  nNew(&pGetCoeff(p));
+  loop
+  {
+    pIter(p);
+    if (p == NULL)
+    {
+      pDelete(&q);
+      a->n = NULL;
+      return res;
+    }
+    a = a->n = (smnumber)omAllocBin(smnrec_bin);
+    a->pos = pGetComp(p);
+    a->m = pGetCoeff(p);
+    nNew(&pGetCoeff(p));
+  }
+}
+
+/*
+* from smnumber to poly
+* destroy a
+*/
+static poly smSmnumber2Poly(number a)
+{
+  poly res;
+
+  if (a == NULL) return NULL;
+  res = pInit();
+  pSetCoeff0(res, a);
+  return res;
+}
+
+/*2
+* check the input
+*/
+static BOOLEAN smCheckSolv(ideal I)
+{ int i = I->ncols;
+  if ((i == 0) || (i != I->rank-1))
+  {
+    WerrorS("wrong dimensions for linsolv");
+    return TRUE;
+  }
+  for(;i;i--)
+  {
+    if(I->m[i-1] == NULL)
+    {
+      WerrorS("singular input for linsolv");
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
Index: kernel/sparsmat.h
===================================================================
--- kernel/sparsmat.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/sparsmat.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,37 @@
+#ifndef SPARSEMAT_H
+#define SPARSEMAT_H
+/*******************************************************************
+ *  Computer Algebra System SINGULAR
+ *
+ *  sparsmat.h: operations with sparse matrices
+ *          (bareis, ...)
+ *
+ *******************************************************************/
+/* $Id: sparsmat.h,v 1.1.1.1 2003-10-06 12:16:03 Singular Exp $ */
+
+
+poly smMult(poly, poly);
+void smPolyDiv(poly, poly);
+poly smMultDiv(poly, poly, const poly);
+void smSpecialPolyDiv(poly, poly);
+/* ----------------- macros ------------------ */
+/* #define OLD_DIV 1 */
+
+#ifdef OLD_DIV
+#define SM_MULT(A,B,C) smMult(A,B)
+#define SM_DIV smPolyDiv
+#else
+#define SM_MULT smMultDiv
+#define SM_DIV smSpecialPolyDiv
+#endif
+
+poly smCallDet(ideal I);
+void smCallBareiss(ideal smat, int x, int y, ideal & M, intvec ** iv);
+void smCallNewBareiss(ideal smat, int x, int y, ideal & M, intvec ** iv);
+ideal smCallSolv(ideal I);
+
+void smRingChange(ring *, sip_sring &, Exponent_t);
+void smRingClean(ring, ip_sring &);
+Exponent_t smExpBound(ideal, int, int, int);
+BOOLEAN smCheckDet(ideal, int, BOOLEAN);
+#endif
Index: kernel/spectrum.cc
===================================================================
--- kernel/spectrum.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/spectrum.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,519 @@
+// ----------------------------------------------------------------------------
+//  spectrum.cc
+//  begin of file
+//  Stephan Endrass, endrass@mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#define SPECTRUM_CC
+
+#include "mod2.h"
+
+#ifdef HAVE_SPECTRUM
+
+#ifdef  SPECTRUM_PRINT
+#include <iostream.h>
+#ifndef  SPECTRUM_IOSTREAM
+#include <stdio.h>
+#endif
+#endif
+
+#include <mylimits.h>
+
+#include "numbers.h"
+#include "polys.h"
+#include "ideals.h"
+#include "kstd1.h"
+#include "stairc.h"
+#include "intvec.h"
+#include "ring.h"
+
+#include "multicnt.h"
+#include "GMPrat.h"
+#include "kmatrix.h"
+#include "npolygon.h"
+#include "splist.h"
+#include "semic.h"
+
+// ----------------------------------------------------------------------------
+//  test if the polynomial  h  has a term of total degree d
+// ----------------------------------------------------------------------------
+
+BOOLEAN hasTermOfDegree( poly h, int d )
+{
+  do
+  {
+    if( pTotaldegree( h )== d )
+      return  TRUE;
+    pIter(h);
+  }
+  while( h!=(poly)NULL );
+
+  return  FALSE;
+}
+
+// ----------------------------------------------------------------------------
+//  test if the polynomial  h  has a constant term
+// ----------------------------------------------------------------------------
+
+static BOOLEAN inline hasConstTerm( poly h )
+{
+  return  hasTermOfDegree(h,0);
+}
+
+// ----------------------------------------------------------------------------
+//  test if the polynomial  h  has a linear term
+// ----------------------------------------------------------------------------
+
+static BOOLEAN inline hasLinearTerm( poly h )
+{
+  return  hasTermOfDegree(h,1);
+}
+
+// ----------------------------------------------------------------------------
+//  test if the ideal  J  has a lead monomial on the axis number  k
+// ----------------------------------------------------------------------------
+
+BOOLEAN hasAxis( ideal J,int k )
+{
+  int i;
+
+  for( i=0; i<IDELEMS(J); i++ )
+  {
+    if (pIsPurePower( J->m[i] ) == k) return TRUE;
+  }
+  return  FALSE;
+}
+
+// ----------------------------------------------------------------------------
+//  test if the ideal  J  has  1  as a lead monomial
+// ----------------------------------------------------------------------------
+
+int     hasOne( ideal J )
+{
+  int i;
+
+  for( i=0; i<IDELEMS(J); i++ )
+  {
+    if (pIsConstant(J->m[i])) return TRUE;
+  }
+  return  FALSE;
+}
+// ----------------------------------------------------------------------------
+//  test if  m  is a multiple of one of the monomials of  f
+// ----------------------------------------------------------------------------
+
+int     isMultiple( poly f,poly m )
+{
+  while( f!=(poly)NULL )
+  {
+    // ---------------------------------------------------
+    //  for a local order  f|m  is only possible if  f>=m
+    // ---------------------------------------------------
+
+    if( pLmCmp( f,m )>=0 )
+    {
+      if( pLmDivisibleByNoComp( f,m ) )
+      {
+        return  TRUE;
+      }
+      else
+      {
+        pIter( f );
+      }
+    }
+    else
+    {
+      return FALSE;
+    }
+  }
+
+  return  FALSE;
+}
+
+// ----------------------------------------------------------------------------
+//  compute the minimal monomial of minimmal  weight>=max_weight
+// ----------------------------------------------------------------------------
+
+poly    computeWC( const newtonPolygon &np,Rational max_weight )
+{
+  poly m  = pOne();
+  poly wc = (poly)NULL;
+  int  mdegree;
+
+  for( int i=1; i<=pVariables; i++ )
+  {
+    mdegree = 1;
+    pSetExp( m,i,mdegree );
+    // pSetm( m );
+    // np.weight_shift does not need pSetm( m ), postpone it
+
+    while(  np.weight_shift( m )<max_weight )
+    {
+      mdegree++;
+      pSetExp( m,i,mdegree );
+      // pSetm( m );
+      // np.weight_shift does not need pSetm( m ), postpone it
+    }
+    pSetm( m );
+
+    if( i==1 || pCmp( m,wc )<0 )
+    {
+      pDelete( &wc );
+      wc = pHead( m );
+    }
+
+    pSetExp( m,i,0 );
+  }
+
+  pDelete( &m );
+
+  return  wc;
+}
+
+// ----------------------------------------------------------------------------
+//  deletes all monomials of  f  which are less than  hc
+// ----------------------------------------------------------------------------
+
+static inline  poly    normalFormHC( poly f,poly hc )
+{
+  poly    *ptr = &f;
+
+  while( (*ptr)!=(poly)NULL )
+  {
+    if( pLmCmp( *ptr,hc )>=0 )
+    {
+      ptr = &(pNext( *ptr ));
+    }
+    else
+    {
+      pDelete( ptr );
+      return  f;
+    }
+  }
+
+  return f;
+}
+
+// ----------------------------------------------------------------------------
+//  deletes all monomials of  f  which are multiples of monomials of  Z
+// ----------------------------------------------------------------------------
+
+static inline  poly    normalFormZ( poly f,poly Z )
+{
+  poly    *ptr = &f;
+
+  while( (*ptr)!=(poly)NULL )
+  {
+    if( !isMultiple( Z,*ptr ) )
+    {
+      ptr = &(pNext( *ptr ));
+    }
+    else
+    {
+      pDeleteLm(ptr);
+    }
+  }
+
+  return f;
+}
+
+// ?? HS:
+// Looks for the shortest polynomial f in stdJ which is divisible
+// by the monimial m, return its index in stdJ
+// ----------------------------------------------------------------------------
+//  Looks for the first polynomial f in stdJ which satisfies m=LT(f)*eta
+//  for a monomial eta. The return eta*f-m and cancel all monomials
+//  which are smaller than the highest corner hc
+// ----------------------------------------------------------------------------
+
+static inline  int     isLeadMonomial( poly m,ideal stdJ )
+{
+  int     length = INT_MAX;
+  int     result = -1;
+
+  for( int i=0; i<IDELEMS(stdJ); i++ )
+  {
+    if( pCmp( stdJ->m[i],m )>=0 && pDivisibleBy( stdJ->m[i],m ) )
+    {
+      int     tmp = pLength( stdJ->m[i] );
+
+      if( tmp < length )
+      {
+        length = tmp;
+        result = i;
+      }
+    }
+  }
+
+  return  result;
+}
+
+// ----------------------------------------------------------------------------
+//  set the exponent of a monomial t an integer array
+// ----------------------------------------------------------------------------
+
+static void    setExp( poly m,int *r )
+{
+  for( int i=pVariables; i>0; i-- )
+  {
+    pSetExp( m,i,r[i-1] );
+  }
+  pSetm( m );
+}
+
+// ----------------------------------------------------------------------------
+//  check if the ordering is a reverse wellordering, i.e. every monomial
+//  is smaller than only finitely monomials
+// ----------------------------------------------------------------------------
+
+static BOOLEAN isWell( void )
+{
+  int b = rBlocks( currRing );
+
+  if( b==3 &&
+      ( currRing->order[0] == ringorder_ds ||
+        currRing->order[0] == ringorder_Ds ||
+        currRing->order[0] == ringorder_ws ||
+        currRing->order[0] == ringorder_Ws ) )
+  {
+    return  TRUE;
+  }
+  else if( b>=3
+  && (( currRing->order[0] ==ringorder_a
+        && currRing->block1[0]==pVariables  )
+    || (currRing->order[0]==ringorder_M
+        && currRing->block1[0]==pVariables*pVariables )))
+  {
+    for( int i=pVariables-1; i>=0; i-- )
+    {
+      if( currRing->wvhdl[0][i]>=0 )
+      {
+        return  FALSE;
+      }
+    }
+    return  TRUE;
+  }
+
+  return  FALSE;
+}
+
+// ----------------------------------------------------------------------------
+//  compute all monomials not in  stdJ  and their normal forms
+// ----------------------------------------------------------------------------
+
+void    computeNF( ideal stdJ,poly hc,poly wc,spectrumPolyList *NF )
+{
+  int         carry,k;
+  multiCnt    C( pVariables,0 );
+  poly        Z = (poly)NULL;
+
+  int         well = isWell( );
+
+  do
+  {
+    poly    m = pOne();
+    setExp( m,C.cnt );
+
+    carry = FALSE;
+
+    k = isLeadMonomial( m,stdJ );
+
+    if( k < 0 )
+    {
+      // ---------------------------
+      //  m  is not a lead monomial
+      // ---------------------------
+
+      NF->insert_node( m,(poly)NULL );
+    }
+    else if( isMultiple( Z,m ) )
+    {
+      // ------------------------------------
+      //  m  is trivially in the ideal  stdJ
+      // ------------------------------------
+
+      pDelete( &m );
+      carry = TRUE;
+    }
+    else if( pCmp( m,hc ) < 0 || pCmp( m,wc ) < 0 )
+    {
+      // -------------------
+      //  we do not need  m
+      // -------------------
+
+      pDelete( &m );
+      carry = TRUE;
+    }
+    else
+    {
+      // --------------------------
+      //  compute lazy normal form
+      // --------------------------
+
+      poly    multiplicant = pDivide( m,stdJ->m[k] );
+      pGetCoeff( multiplicant ) = nInit(1);
+
+      poly    nf = pMult_mm( pCopy( stdJ->m[k] ), multiplicant );
+
+      pDelete( &multiplicant );
+
+      nf = normalFormHC( nf,hc );
+
+      if( pNext( nf )==(poly)NULL )
+      {
+        // ----------------------------------
+        //  normal form of  m  is  m  itself
+        // ----------------------------------
+
+        pDelete( &nf );
+        NF->delete_monomial( m );
+        Z = pAdd( Z,m );
+        carry = TRUE;
+      }
+      else
+      {
+        nf = normalFormZ( nf,Z );
+
+        if( pNext( nf )==(poly)NULL )
+        {
+          // ----------------------------------
+          //  normal form of  m  is  m  itself
+          // ----------------------------------
+
+          pDelete( &nf );
+          NF->delete_monomial( m );
+          Z = pAdd( Z,m );
+          carry = TRUE;
+        }
+        else
+        {
+          // ------------------------------------
+          //  normal form of  m  is a polynomial
+          // ------------------------------------
+
+          pNorm( nf );
+          if( well==TRUE )
+          {
+            NF->insert_node( m,nf );
+          }
+          else
+          {
+            poly    nfhard = kNF( stdJ,(ideal)NULL,pNext( nf ),0,0 );
+            nfhard = normalFormHC( nfhard,hc );
+            nfhard = normalFormZ ( nfhard,Z );
+
+            if( nfhard==(poly)NULL )
+            {
+              NF->delete_monomial( m );
+              Z = pAdd( Z,m );
+              carry = TRUE;
+            }
+            else
+            {
+              pDelete( &pNext( nf ) );
+              pNext( nf ) = nfhard;
+              NF->insert_node( m,nf );
+            }
+          }
+        }
+      }
+    }
+  }
+  while( C.inc( carry ) );
+
+  // delete single monomials
+
+  BOOLEAN  not_finished;
+
+  do
+  {
+    not_finished = FALSE;
+
+    spectrumPolyNode  *node = NF->root;
+
+    while( node!=(spectrumPolyNode*)NULL )
+    {
+      if( node->nf!=(poly)NULL && pNext( node->nf )==(poly)NULL )
+      {
+        NF->delete_monomial( node->nf );
+        not_finished = TRUE;
+        node = (spectrumPolyNode*)NULL;
+      }
+      else
+      {
+        node = node->next;
+      }
+    }
+  } while( not_finished );
+
+  pDelete( &Z );
+}
+
+// ----------------------------------------------------------------------------
+//  check if  currRing is local
+// ----------------------------------------------------------------------------
+
+BOOLEAN ringIsLocal( void )
+{
+  poly    m   = pOne();
+  poly    one = pOne();
+  BOOLEAN res=TRUE;
+
+  for( int i=pVariables; i>0; i-- )
+  {
+    pSetExp( m,i,1 );
+    pSetm( m );
+
+    if( pCmp( m,one )>0 )
+    {
+      res=FALSE;
+      break;
+    }
+    pSetExp( m,i,0 );
+  }
+
+  pDelete( &m );
+  pDelete( &one );
+
+  return  res;
+}
+
+// ----------------------------------------------------------------------------
+// print error message corresponding to spectrumState state:
+// ----------------------------------------------------------------------------
+void spectrumPrintError(spectrumState state)
+{
+  switch( state )
+  {
+    case spectrumZero:
+      WerrorS( "polynomial is zero" );
+      break;
+    case spectrumBadPoly:
+      WerrorS( "polynomial has constant term" );
+      break;
+    case spectrumNoSingularity:
+      WerrorS( "not a singularity" );
+      break;
+    case spectrumNotIsolated:
+      WerrorS( "the singularity is not isolated" );
+      break;
+    case spectrumNoHC:
+      WerrorS( "highest corner cannot be computed" );
+      break;
+    case spectrumDegenerate:
+      WerrorS( "principal part is degenerate" );
+      break;
+    case spectrumOK:
+      break;
+
+    default:
+      WerrorS( "unknown error occurred" );
+      break;
+  }
+}
+#endif /* HAVE_SPECTRUM */
+// ----------------------------------------------------------------------------
+//  spectrum.cc
+//  end of file
+// ----------------------------------------------------------------------------
Index: kernel/spectrum.h
===================================================================
--- kernel/spectrum.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/spectrum.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,38 @@
+// ----------------------------------------------------------------------------
+//  spectrum.h
+//  begin of file
+//  Stephan Endrass, endrass@mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#ifndef SPECTRUM_H
+#define SPECTRUM_H
+#include "npolygon.h"
+#include "splist.h"
+
+BOOLEAN    spectrumProc ( leftv,leftv );
+BOOLEAN    spectrumfProc( leftv,leftv );
+BOOLEAN    spaddProc    ( leftv,leftv,leftv );
+BOOLEAN    spmulProc    ( leftv,leftv,leftv );
+BOOLEAN    semicProc   ( leftv,leftv,leftv );
+BOOLEAN    semicProc3   ( leftv,leftv,leftv,leftv );
+BOOLEAN    hasTermOfDegree( poly h, int d );
+int        hasOne( ideal J );
+BOOLEAN    hasAxis( ideal J,int k );
+poly       computeWC( const newtonPolygon &np,Rational max_weight );
+void       computeNF( ideal stdJ,poly hc,poly wc,spectrumPolyList *NF );
+void       spectrumPrintError(spectrumState state);
+BOOLEAN    ringIsLocal( void );
+
+BOOLEAN inline hasConstTerm( poly h )
+{ return  hasTermOfDegree(h,0); }
+BOOLEAN inline hasLinearTerm( poly h )
+{ return  hasTermOfDegree(h,1); }
+
+
+#endif
+
+// ----------------------------------------------------------------------------
+//  spectrum.h
+//  end of file
+// ----------------------------------------------------------------------------
Index: kernel/splist.cc
===================================================================
--- kernel/splist.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/splist.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,380 @@
+// ----------------------------------------------------------------------------
+//  splist.cc
+//  begin of file
+//  Stephan Endrass, endrass@mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+#define SPLIST_CC
+
+#include "mod2.h"
+
+#ifdef HAVE_SPECTRUM
+
+#ifdef  SPLIST_PRINT
+#include <iostream.h>
+#ifndef SPLIST_IOSTREAM
+#include <stdio.h>
+#endif
+#endif
+
+#include "structs.h"
+#include "GMPrat.h"
+#include "numbers.h"
+#include "polys.h"
+#include "npolygon.h"
+#include "splist.h"
+#include "intvec.h"
+
+// ------------------------
+//  class spectrumPolyNode
+// ------------------------
+
+// ----------------------------------------------------------------------------
+//  Initialize a  spectrumPolyNode  with zero
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyNode::copy_zero( void )
+{
+    next   = (spectrumPolyNode*)NULL;
+    mon    = (poly)NULL;
+    weight = (Rational)0;
+    nf     = (poly)NULL;
+}
+
+// ----------------------------------------------------------------------------
+//  Inizialize a  spectrumPolyNode  shallow from data
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyNode::copy_shallow(
+                spectrumPolyNode *pnode,poly m,const Rational &w,poly f )
+{
+    next   = pnode;
+    mon    = m;
+    weight = w;
+    nf     = f;
+}
+
+// ----------------------------------------------------------------------------
+//  Inizialize a  spectrumPolyNode  shallow from another  spectrumPolyNode
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyNode::copy_shallow( spectrumPolyNode &node )
+{
+    next   = node.next;
+    mon    = node.mon;
+    weight = node.weight;
+    nf     = node.nf;
+}
+
+// ----------------------------------------------------------------------------
+//  Zero constructor for  spectrumPolyNode
+// ----------------------------------------------------------------------------
+
+spectrumPolyNode::spectrumPolyNode( )
+{
+    copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  Data constructor for  spectrumPolyNode  is shallow
+// ----------------------------------------------------------------------------
+
+spectrumPolyNode::spectrumPolyNode(
+        spectrumPolyNode *pnode,poly m,const Rational &w,poly f )
+{
+    copy_shallow( pnode,m,w,f );
+}
+
+// ----------------------------------------------------------------------------
+//  Destructor is empty since we construct our objects shallow
+// ----------------------------------------------------------------------------
+
+spectrumPolyNode::~spectrumPolyNode( )
+{
+    if( mon!=(poly)NULL ) pDelete( &mon );
+    if( nf !=(poly)NULL ) pDelete( &nf );
+    copy_zero( );
+}
+
+// ------------------------
+//  class spectrumPolyList
+// ------------------------
+
+// ----------------------------------------------------------------------------
+//  Initialize a  spectrumPolyList  with zero
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyList::copy_zero( void )
+{
+    root = (spectrumPolyNode*)NULL;
+    N    = 0;
+    np   = (newtonPolygon*)NULL;
+}
+
+// ----------------------------------------------------------------------------
+//  Inizialize a  spectrumPolyList  shallow from data
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyList::copy_shallow(
+                spectrumPolyNode *node,int k,newtonPolygon *npolygon )
+{
+    root = node;
+    N    = k;
+    np   = npolygon;
+}
+
+// ----------------------------------------------------------------------------
+//  Inizialize a  spectrumPolyList  shallow from another  spectrumPolyList
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyList::copy_shallow( spectrumPolyList &splist )
+{
+    copy_shallow( splist.root,splist.N,splist.np );
+}
+
+// ----------------------------------------------------------------------------
+//  Zero constructor for  spectrumPolyList
+// ----------------------------------------------------------------------------
+
+spectrumPolyList::spectrumPolyList( )
+{
+    copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  Data constructor for  spectrumPolyList
+// ----------------------------------------------------------------------------
+
+spectrumPolyList::spectrumPolyList( newtonPolygon *npolygon )
+{
+    copy_shallow( (spectrumPolyNode*)NULL,0,npolygon );
+}
+
+// ----------------------------------------------------------------------------
+//  Destuctor for  spectrumPolyList
+// ----------------------------------------------------------------------------
+
+spectrumPolyList::~spectrumPolyList( )
+{
+    spectrumPolyNode *node;
+
+    while( root!=(spectrumPolyNode*)NULL )
+    {
+        node = root->next;
+        delete root;
+        root = node;
+    }
+
+    copy_zero( );
+}
+
+// ----------------------------------------------------------------------------
+//  Insert a new node into a  spectrumPolyList  at position k
+//      If the list is sorted, then
+//      the new node ist inserted such that the list remains sorted.
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyList::insert_node( poly m,poly f )
+{
+    #ifdef SPLIST_DEBUG
+        if( np==(newtonPolygon*)NULL )
+        {
+            #ifdef SPLIST_PRINT
+            #ifdef SPLIST_IOSTREAM
+                cerr << "void    spectrumPolyList::insert_node( poly f )" << endl;
+                cerr << "    no Newton polygon" << endl;
+                cerr << "    exiting..." << endl;
+            #else
+                fprintf( stderr,"void    spectrumPolyList::insert_node( poly f )\n" );
+                fprintf( stderr,"    no Newton polygon\n" );
+                fprintf( stderr,"    exiting...\n" );
+            #endif
+            #endif
+
+            exit( 1 );
+        }
+    #endif
+
+    spectrumPolyNode    *newnode = new spectrumPolyNode(
+        (spectrumPolyNode*)NULL,m,np->weight_shift( m ),f );
+
+    if( N==0 ||
+              root->weight>newnode->weight ||
+            ( root->weight==newnode->weight &&
+              pCmp( root->mon,newnode->mon )<0 ) )
+    {
+        // ----------------------
+        //  insert at position 0
+        // ----------------------
+
+        newnode->next = root;
+        root          = newnode;
+    }
+    else if( N==1 )
+    {
+        // ---------------
+        //  insert at end
+        // ---------------
+
+        root->next    = newnode;
+    }
+    else
+    {
+        // ----------------------------
+        //  insert according to weight
+        // ----------------------------
+
+        spectrumPolyNode *actual = root;
+        spectrumPolyNode *next   = root->next;
+
+        while( next!=(spectrumPolyNode*)NULL &&
+               ( newnode->weight>next->weight ||
+               ( newnode->weight==next->weight &&
+                 pCmp( newnode->mon,next->mon )<0 ) ) )
+        {
+            actual = next;
+            next   = next->next;
+        }
+
+        actual->next = newnode;
+        newnode->next = next;
+    }
+    N++;
+}
+
+// ----------------------------------------------------------------------------
+//  Delete a node from a  spectrumPolyList
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyList::delete_node( spectrumPolyNode **node )
+{
+    spectrumPolyNode *foo = *node;
+    *node = (*node)->next;
+    delete foo;
+    N--;
+}
+
+// ----------------------------------------------------------------------------
+//  Delete all nodes where   node->mon  is a multiple of  m
+//  In every node delete all instances of  m  in  node->nf
+// ----------------------------------------------------------------------------
+
+void    spectrumPolyList::delete_monomial( poly m )
+{
+    spectrumPolyNode **node = &root;
+    poly              *f;
+
+    m = pCopy( m );
+
+    while( *node!=(spectrumPolyNode*)NULL )
+    {
+        if( pCmp( m,(*node)->mon )>=0 && pLmDivisibleByNoComp( m,(*node)->mon ) )
+        {
+            delete_node( node );
+        }
+        else if( (*node)->nf!=(poly)NULL )
+        {
+            f = &((*node)->nf);
+
+            while( *f!=(poly)NULL )
+            {
+                if( pCmp( m,*f )>=0 && pLmDivisibleByNoComp( m,*f ) )
+                {
+                    pDeleteLm(f);
+                }
+                else
+                    {
+                    f = &(pNext( *f ));
+                }
+            }
+
+            if( (*node)->nf==(poly)NULL )
+            {
+                delete_node( node );
+            }
+            else
+            {
+                node = &((*node)->next);
+            }
+        }
+        else
+        {
+            node = &((*node)->next);
+        }
+    }
+    pDelete( &m );
+}
+
+// ----------------------------------------------------------------------------
+//  Print a  spectrumPolyList
+// ----------------------------------------------------------------------------
+
+#ifdef SPLIST_PRINT
+ostream & operator << ( ostream &s,const spectrumPolyList &l )
+{
+    #ifdef SPLIST_IOSTREAM
+        s << "elements: " << l.N << endl;
+        s << "{";
+    #else
+        fprintf( stdout,"elements: %d\n",l.N );
+        fprintf( stdout,"{" );
+    #endif
+
+    if( l.root!=(spectrumPolyNode*)NULL )
+    {
+        #ifdef SPLIST_IOSTREAM
+            s << "(";
+            pWrite0( l.root->mon );
+            s << "=>";
+            pWrite0( l.root->nf );
+            cout << "," << l.root->weight << ")" << endl;
+        #else
+            fprintf( stdout,"(" );
+            pWrite0( l.root->mon );
+            fprintf( stdout,"=>" );
+            pWrite0( l.root->nf );
+            fprintf( stdout,"," );
+            cout << l.root->weight;
+            fprintf( stdout,")\n" );
+        #endif
+
+        spectrumPolyNode *node = l.root->next;
+
+        while( node!=(spectrumPolyNode*)NULL )
+        {
+            #ifdef SPLIST_IOSTREAM
+                s << ",(";
+                pWrite0( node->mon );
+                s << "=>";
+                pWrite0( node->nf );
+                cout << "," << node->weight << ")" << endl;
+            #else
+                fprintf( stdout,",(" );
+                pWrite0( node->mon );
+                fprintf( stdout,"=>" );
+                pWrite0( node->nf );
+                fprintf( stdout,"," );
+                cout << node->weight;
+                fprintf( stdout,")\n" );
+            #endif
+
+            node = node->next;
+        }
+    }
+    #ifdef SPLIST_IOSTREAM
+        s << "}";
+    #else
+        fprintf( stdout,"}" );
+    #endif
+
+    return  s;
+}
+#endif
+
+#endif /* HAVE_SPECTRUM */
+// ----------------------------------------------------------------------------
+//  splist.cc
+//  end of file
+// ----------------------------------------------------------------------------
+
Index: kernel/splist.h
===================================================================
--- kernel/splist.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/splist.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,88 @@
+// ----------------------------------------------------------------------------
+//  splist.h
+//  begin of file
+//  Stephan Endrass, endrass@mathematik.uni-mainz.de
+//  23.7.99
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+//  Description: the class  spectrumPolyList  is to hold monomials
+//  and their normal forms with respect to a given standard basis
+//  and a given ordering. On this list we run a standard basis
+//  conversion algorithm to compute  the spectrum
+// ----------------------------------------------------------------------------
+
+#ifndef SPLIST_H
+#define SPLIST_H
+
+#include "npolygon.h"
+
+enum    spectrumState
+{
+    spectrumOK,
+    spectrumZero,
+    spectrumBadPoly,
+    spectrumNoSingularity,
+    spectrumNotIsolated,
+    spectrumDegenerate,
+    spectrumWrongRing,
+    spectrumNoHC,
+    spectrumUnspecErr
+};
+
+// ----------------------------------------------------------------------------
+
+class spectrumPolyNode
+{
+public:
+
+    spectrumPolyNode    *next;
+    poly                mon;
+    Rational            weight;
+    poly                nf;
+
+    spectrumPolyNode( );
+    spectrumPolyNode( spectrumPolyNode*,poly,const Rational&,poly );
+    ~spectrumPolyNode( );
+
+    void    copy_zero   ( void );
+    void    copy_shallow( spectrumPolyNode*,poly,const Rational&,poly );
+    void    copy_shallow( spectrumPolyNode& );
+};
+
+// ----------------------------------------------------------------------------
+
+class spectrumPolyList
+{
+public:
+
+    spectrumPolyNode       *root;
+    int             N;
+    newtonPolygon   *np;
+
+    spectrumPolyList( );
+    spectrumPolyList( newtonPolygon* );
+    ~spectrumPolyList( );
+
+    void    copy_zero   ( void );
+    void    copy_shallow( spectrumPolyNode*,int,newtonPolygon* );
+    void    copy_shallow( spectrumPolyList& );
+
+    void    insert_node( poly,poly );
+    void    delete_node( spectrumPolyNode** );
+
+    void    delete_monomial( poly );
+
+    spectrumState  spectrum( lists*,int );
+
+    #ifdef SPLIST_PRINT
+        friend ostream & operator << ( ostream&,const spectrumPolyList& );
+    #endif
+};
+
+#endif /* SPLIST_H */
+
+// ----------------------------------------------------------------------------
+//  splist.h
+//  end of file
+// ----------------------------------------------------------------------------
Index: kernel/stairc.h
===================================================================
--- kernel/stairc.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/stairc.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,34 @@
+#ifndef STAIRC_H
+#define STAIRC_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: stairc.h,v 1.1.1.1 2003-10-06 12:16:03 Singular Exp $ */
+/*
+* ABSTRACT
+*/
+
+#include "structs.h"
+
+void scComputeHC(ideal s,ideal Q, int  k,poly &hEdge, ring tailRing = currRing);
+
+intvec * scIndIntvec(ideal S, ideal Q=NULL);
+lists scIndIndset(ideal S, BOOLEAN all, ideal Q=NULL);
+int scDimInt(ideal  s,ideal Q=NULL);
+int scMultInt(ideal  s,ideal Q=NULL);
+int scMult0Int(ideal  s,ideal Q=NULL);
+void scPrintDegree(int co, int mu);
+int scDegree(ideal  s,ideal Q=NULL);
+
+ideal scKBase(int deg, ideal  s, ideal Q=NULL);
+
+intvec * hHstdSeries(ideal S, intvec *modulweight, intvec *wdegree,
+                     ideal Q=NULL, ring tailRing = currRing);
+intvec * hFirstSeries(ideal S, intvec *modulweight, ideal Q=NULL, intvec *wdegree=NULL, ring tailRing = currRing);
+intvec * hSecondSeries(intvec *hseries1);
+
+void hLookSeries(ideal S, intvec *modulweight, ideal Q=NULL);
+
+#endif
+
+
Index: kernel/stamp-h
===================================================================
--- kernel/stamp-h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/stamp-h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1 @@
+timestamp
Index: kernel/static.h
===================================================================
--- kernel/static.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/static.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1 @@
+#undef HAVE_STATIC
Index: kernel/structs.h
===================================================================
--- kernel/structs.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/structs.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,760 @@
+#ifndef STRUCTS_H
+#define STRUCTS_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: structs.h,v 1.1.1.1 2003-10-06 12:15:53 Singular Exp $ */
+/*
+* ABSTRACT
+*/
+
+#include <string.h> /* for memset */
+
+#define LONGALGNEW
+/* standard types */
+typedef unsigned char  uchar ;
+typedef unsigned short CARDINAL;
+typedef short BOOLEAN;
+
+typedef void * Sy_reference;
+#define ADDRESS Sy_reference
+#define BITSET  unsigned int
+
+/* EXPONENT_TYPE is determined by configure und defined in mod2.h */
+/* the following defines should really go into mod2.h,
+   but configure dislikes it */
+
+
+// define if a*b is with mod instead of tables
+#if defined(i386)
+// seems to be better on i386 processors
+#define HAVE_MULT_MOD
+#ifdef HAVE_MULT_MOD
+/* #define HAVE_DIV_MOD*/
+#endif
+#endif
+
+typedef long Exponent_t;
+typedef long Order_t;
+
+enum tHomog
+{
+   isNotHomog = FALSE,
+   isHomog    = TRUE,
+   testHomog
+};
+enum noeof_t
+{
+  noeof_brace = 1,
+  noeof_asstring,
+  noeof_block,
+  noeof_bracket,
+  noeof_comment,
+  noeof_procname,
+  noeof_string
+};
+
+enum n_coeffType
+{
+  n_unknown=0,
+  n_Zp,
+  n_Q,
+  n_R,
+  n_GF,
+  n_long_R,
+  n_Zp_a,
+  n_Q_a,
+  n_long_C
+};
+
+#ifdef HAVE_PLURAL
+enum nc_type
+{
+  nc_general=0, /* yx=q xy+... */
+  nc_skew, /*1*/ /* yx=q xy */
+  nc_lie,  /*2*/ /* yx=xy+... */
+  nc_undef /*3*/  /* for internal reasons */
+};
+#endif
+
+
+/* C++-part */
+#ifdef __cplusplus
+class ip_smatrix;
+class idrec;
+class intvec;
+class sleftv;
+class slists;
+class sattr;
+class skStrategy;
+class ssyStrategy;
+class procinfo;
+class namerec;
+class kBucket;
+class sBucket;
+#endif
+
+struct n_Procs_s;
+struct sip_sring;
+struct sip_sideal;
+struct sip_link;
+struct spolynom;
+struct _ssubexpr;
+struct _sssym;
+struct snumber;
+struct sip_command;
+struct sip_package;
+struct s_si_link_extension;
+#ifndef LONGALGNEW
+struct reca;
+#endif /* not LONGALGNEW */
+
+typedef struct  n_Procs_s  n_Procs_s;
+
+#ifdef HAVE_PLURAL
+struct nc_struct;
+typedef struct nc_struct   nc_struct;
+#endif
+
+typedef struct _ssubexpr   sSubexpr;
+typedef struct _sssym      ssym;
+typedef struct spolyrec    polyrec;
+typedef struct sip_sideal  ip_sideal;
+typedef struct sip_smap    ip_smap;
+typedef struct sip_sring   ip_sring;
+typedef struct sip_link    ip_link;
+typedef struct sip_command ip_command;
+typedef struct sip_package ip_package;
+
+/* the pointer types */
+typedef char *             char_ptr;
+typedef int  *             int_ptr;
+typedef short *            short_ptr;
+typedef void *             void_ptr;
+typedef ip_sring *         ring;
+typedef int                idtyp;
+typedef struct snumber *   number;
+typedef polyrec *          poly;
+typedef poly *             polyset;
+typedef ip_sideal *        ideal;
+typedef ip_smap *          map;
+typedef struct sideal_list *      ideal_list;
+typedef ideal *            resolvente;
+typedef union uutypes      utypes;
+typedef ip_command *       command;
+typedef struct s_si_link_extension *si_link_extension;
+#ifndef LONGALGNEW
+typedef struct reca *      napoly;
+#else /* LONGALGNEW */
+typedef polyrec *   napoly;
+#endif /* LONGALGNEW */
+
+#ifdef __cplusplus
+typedef idrec *            idhdl;
+typedef ip_smatrix *       matrix;
+typedef ip_link *          si_link;
+typedef sleftv *           leftv;
+typedef slists *           lists;
+typedef sSubexpr *         Subexpr;
+typedef sattr *            attr;
+typedef skStrategy *       kStrategy;
+typedef ip_package *       package;
+typedef ssyStrategy *      syStrategy;
+typedef procinfo *         procinfov;
+typedef namerec *          namehdl;
+typedef kBucket*           kBucket_pt;
+typedef sBucket*           sBucket_pt;
+typedef struct p_Procs_s p_Procs_s;
+
+// for hdegree.cc
+typedef struct sindlist indlist;
+typedef indlist * indset;
+struct sindlist
+{
+  indset nx;
+  intvec * set;
+};
+
+// for longalg.cc
+struct snaIdeal
+{
+  int anz;
+  napoly *liste;
+};
+typedef struct snaIdeal * naIdeal;
+
+
+// for sparsemat.cc
+typedef struct smprec sm_prec;
+typedef sm_prec * smpoly;
+struct smprec
+{
+  smpoly n;            // the next element
+  int pos;             // position
+  int e;               // level
+  poly m;              // the element
+  float f;             // complexity of the element
+};
+
+struct _scmdnames
+{
+  char *name;
+  short alias;
+  short tokval;
+  short toktype;
+};
+typedef struct _scmdnames cmdnames;
+
+typedef number (*numberfunc)(number a,number b);
+typedef number (*nMapFunc)(number a);
+struct n_Procs_s
+{
+   n_Procs_s* next;
+   // the union stuff
+   // Zp:
+   int npPrimeM;
+   int npPminus1M;
+   #ifdef HAVE_DIV_MOD
+   CARDINAL *npInvTable;
+   #endif
+   #if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD)
+   CARDINAL *npExpTable;
+   CARDINAL *npLogTable;
+   #endif
+   // Zp_a, Q_a
+
+   // general stuff
+   numberfunc nMult, nSub ,nAdd ,nDiv, nIntDiv, nIntMod, nExactDiv;
+   void    (*nNew)(number * a);
+   number  (*nInit)(int i);
+   number  (*nPar)(int i);
+   int     (*nParDeg)(number n);
+   int     (*nSize)(number n);
+   int     (*nInt)(number &n);
+   number  (*nNeg)(number a);
+   number  (*nInvers)(number a);
+   number  (*nCopy)(number a);
+   number  (*cfCopy)(number a, const ring r);
+   number  (*nRePart)(number a);
+   number  (*nImPart)(number a);
+   void    (*nWrite)(number &a);
+   char *  (*nRead)(char * s, number * a);
+   void    (*nNormalize)(number &a);
+   BOOLEAN (*nGreater)(number a,number b),
+           (*nEqual)(number a,number b),
+           (*nIsZero)(number a),
+           (*nIsOne)(number a),
+           (*nIsMOne)(number a),
+           (*nGreaterZero)(number a);
+   void    (*nPower)(number a, int i, number * result);
+   number  (*n_GetDenom)(number &n, const ring r);
+   number  (*nGcd)(number a, number b, const ring r);
+   number  (*nLcm)(number a, number b, const ring r);
+   void    (*cfDelete)(number * a, const ring r);
+   nMapFunc (*cfSetMap)(ring src, ring dst);
+   char *  (*nName)(number n);
+   void    (*nInpMult)(number &a, number b, ring r);
+//extern number  (*nMap)(number from);
+
+   number nNULL; /* the 0 as constant */
+   int     char_flag;
+   int     ref;
+   short   nChar;
+   n_coeffType type;
+};
+/* current ring stuff */
+
+extern ring      currRing;
+extern ideal     currQuotient;
+extern idhdl      currRingHdl;
+
+#ifndef HAVE_NS
+extern idhdl      idroot;
+#define IDROOT idroot
+#endif /* ! HAVE_NS */
+
+#ifdef HAVE_NS
+extern idhdl currPackHdl;
+extern idhdl basePackHdl;
+extern package currPack;
+extern package basePack;
+#define IDROOT (currPack->idroot)
+#endif /* HAVE_NS */
+
+/* the function pointer types */
+
+typedef long     (*pLDegProc)(poly p, int *length, ring r= currRing);
+typedef long     (*pFDegProc)(poly p, ring r = currRing);
+typedef void     (*p_SetmProc)(poly p, ring r = currRing);
+
+typedef enum
+{
+  ro_dp, // ordering is a degree ordering
+  ro_wp, // ordering is a weighted degree ordering
+  ro_wp_neg, // ordering is a weighted degree ordering
+             // with possibly negative weights
+  ro_cp,    // ordering duplicates variables
+  ro_syzcomp, // ordering indicates "subset" of component number
+  ro_syz, // ordering  with component number >syzcomp is lower
+  ro_none
+}
+ro_typ;
+
+// ordering is a degree ordering
+struct sro_dp
+{
+  short place;  // where degree is stored (in L):
+  short start;  // bounds of ordering (in E):
+  short end;
+};
+typedef struct sro_dp sro_dp;
+
+// ordering is a weighted degree ordering
+struct sro_wp
+{
+  short place;  // where weighted degree is stored (in L)
+  short start;  // bounds of ordering (in E)
+  short end;
+  int *weights; // pointers into wvhdl field
+};
+typedef struct sro_wp sro_wp;
+
+// ordering duplicates variables
+struct sro_cp
+{
+  short place;  // where start is copied to (in E)
+  short start;  // bounds of sources of copied variables (in E)
+  short end;
+};
+typedef struct sro_cp sro_cp;
+
+// ordering indicates "subset" of component number
+struct sro_syzcomp
+{
+  short place;  // where the index is stored (in L)
+  long *ShiftedComponents; // pointer into index field
+  int* Components;
+#ifdef PDEBUG
+  long length;
+#endif
+};
+typedef struct sro_syzcomp sro_syzcomp;
+
+// ordering  with component number >syzcomp is lower
+struct sro_syz
+{
+  short place;       // where the index is stored (in L)
+  int limit;         // syzcomp
+  int* syz_index;    // mapping Component -> SyzIndex for Comp <= limit
+  int  curr_index;   // SyzIndex for Component > limit
+};
+
+typedef struct sro_syz sro_syz;
+
+#ifndef OM_ALLOC_H
+struct omBin_s;
+#endif
+
+struct sro_ord
+{
+  ro_typ  ord_typ;
+  int     order_index; // comes from r->order[order_index]
+  union
+  {
+     sro_dp dp;
+     sro_wp wp;
+     sro_cp cp;
+     sro_syzcomp syzcomp;
+     sro_syz syz;
+  } data;
+};
+
+#ifdef HAVE_PLURAL
+struct nc_struct
+{
+  short ref;
+  nc_type type;
+  ring basering; // the ring C,D,.. live in
+  matrix C;
+  matrix D;
+  matrix *MT;
+  matrix COM;
+  int *MTsize;
+  int IsSkewConstant; /* indicates whethere coeffs C_ij are all equal */
+  /* effective together with nc_type=nc_skew */
+};
+#endif
+
+struct sip_sring
+{
+  idhdl      idroot; /* local objects */
+  int*       order;  /* array of orderings */
+  int*       block0; /* starting pos.*/
+  int*       block1; /* ending pos.*/
+  char**     parameter; /* names of parameters */
+  number     minpoly;
+  int**      wvhdl;  /* array of weight vectors */
+  char **    names;  /* array of variable names */
+
+  unsigned long options; /* ring dependent options */
+
+  // what follows below here should be set by rComplete, _only_
+  long      *ordsgn;  /* array of +/- 1 (or 0) for comparing monomials */
+                       /*  ExpL_Size entries*/
+
+  // is NULL for lp or N == 1, otherwise non-NULL (with OrdSize > 0 entries) */
+  sro_ord*   typ;   /* array of orderings + sizes, OrdSize entries */
+
+  ideal      qideal; /* extension to the ring structure: qring */
+
+
+  int      *VarOffset;
+  int*     firstwv;
+
+  struct omBin_s*   PolyBin; /* Bin from where monoms are allocated */
+  short      ch;     /* characteristic */
+  short      float_len; /* additional char-flags */
+  short      float_len2; /* additional char-flags */
+
+  short      N;      /* number of vars */
+
+  short      P;      /* number of pars */
+  short      OrdSgn; /* 1 for polynomial rings, -1 otherwise */
+
+  short     firstBlockEnds;
+
+
+  BOOLEAN   VectorOut;
+  BOOLEAN   ShortOut;
+  BOOLEAN   CanShortOut;
+  BOOLEAN   LexOrder;
+  // TRUE if the monomial ordering has polynomial and power series blocks
+  BOOLEAN   MixedOrder;
+  // 1 for lex ordering (except ls), -1 otherwise
+  BOOLEAN   ComponentOrder;
+
+
+  // what follows below here should be set by rComplete, _only_
+  // contains component, but no weight fields in E */
+  short      ExpL_Size; // size of exponent vector in long
+  short      CmpL_Size; // portions which need to be compared
+  /* number of long vars in exp vector:
+     long vars are those longs in the exponent vector which are
+     occupied by variables, only */
+  short     VarL_Size;
+
+  short      BitsPerExp; /* number of bits per exponent */
+  short      ExpPerLong; /* maximal number of Exponents per long */
+
+  short      pCompIndex; /* p->exp.e[pCompIndex] is the component */
+  short      pOrdIndex; /* p->exp[pOrdIndex] is pGetOrd(p) */
+
+  short      OrdSize; /* size of ord vector (in sro_ord) */
+
+
+  short      ref; /* reference counter to the ring */
+
+  /* if >= 0, long vars in exp vector are consecutive and start there
+     if <  0, long vars in exp vector are not consecutive */
+  short     VarL_LowIndex;
+  // number of exponents in r->VarL_Offset[0]
+  // is minimal number of exponents in a long var
+  short     MinExpPerLong;
+
+  /* if this is > 0, then NegWeightL_Offset[0..size_1] is index of longs in
+   ExpVector whose values need an offset due to negative weights */
+  short     NegWeightL_Size;
+  /* array of NegWeigtL_Size indicies */
+  int*      NegWeightL_Offset;
+
+  /* array of size VarL_Size,
+     VarL_Offset[i] gets i-th long var in exp vector */
+  int*      VarL_Offset;
+
+  /* mask for getting single exponents */
+  unsigned long bitmask;
+  /* mask used for divisiblity tests */
+  unsigned long divmask;
+
+  p_Procs_s*    p_Procs;
+
+  /* FDeg and LDeg */
+  pFDegProc     pFDeg;
+  pLDegProc     pLDeg;
+
+  /* as it was determined by rComplete */
+  pFDegProc     pFDegOrig;
+  /* and as it was determined before rOptimizeLDeg */
+  pLDegProc     pLDegOrig;
+
+  p_SetmProc    p_Setm;
+  n_Procs_s*    cf;
+  ring          algring;
+#ifdef HAVE_PLURAL
+  nc_struct     *nc;
+#endif
+};
+
+struct sip_sideal
+{
+  poly*  m;
+  long rank;
+  int nrows;
+  int ncols;
+  #define IDELEMS(i) ((i)->ncols)
+  inline int& idelems(void) { return ncols; }
+};
+
+struct sip_smap
+{
+  poly *m;
+  char *preimage;
+  int nrows;
+  int ncols;
+};
+
+struct sideal_list
+{
+  ideal_list next;
+  ideal      d;
+};
+#endif /* __cplusplus */
+
+
+
+/*
+**  7. runtime procedures/global data
+*/
+
+/* 7.1 C-routines : */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void  m2_end(short i);
+#ifdef __cplusplus
+}
+#endif
+
+/* 7.2 C++-routines : */
+
+#ifdef __cplusplus
+int   inits(void);
+int   IsPrime(int i);
+#ifdef buildin_rand
+extern int siSeed;
+int siRand();
+#endif
+#endif
+
+/*the general set of std-options --> kutil.cc */
+extern BITSET test;
+/*the general set of verbose-options --> febase.cc */
+#ifdef __cplusplus
+extern "C" BITSET verbose;
+#else
+extern BITSET verbose;
+#endif
+/*debugging the bison grammar --> grammar.cc*/
+#ifdef YYDEBUG
+#if YYDEBUG
+extern int    yydebug;
+#endif
+#endif
+
+extern int      yylineno;
+extern char     my_yylinebuf[80];
+
+#define loop for(;;)
+
+#ifndef ABS
+#define ABS(x) ((x)<0?(-(x)):(x))
+#endif
+
+#if defined(__cplusplus)
+inline int si_max(const int a, const int b)  { return (a>b) ? a : b; }
+inline int si_min(const int a, const int b)  { return (a<b) ? a : b; }
+#if defined(DecAlpha_Linux) || defined(IA64_Linux)
+inline long si_max(const long a, const long b)  { return (a>b) ? a : b; }
+inline long si_min(const long a, const long b)  { return (a<b) ? a : b; }
+#endif
+#else
+#define si_max(A,B) ((A) > (B) ? (A) : (B))
+#define si_min(A,B) ((A) < (B) ? (A) : (B))
+#endif
+
+/*
+**  Set operations (small sets only)
+*/
+
+#define Sy_bit(x)     ((unsigned)1<<(x))
+#define Sy_inset(x,s) ((Sy_bit(x)&(s))?TRUE:FALSE)
+#define BTEST1(a)     Sy_inset((a), test)
+#define BVERBOSE(a)   Sy_inset((a), verbose)
+
+/*
+** defines for BITSETs
+*/
+
+#define V_SHOW_MEM  2
+#define V_YACC      3
+#define V_REDEFINE  4
+#define V_READING   5
+#define V_LOAD_LIB  6
+#define V_DEBUG_LIB 7
+#define V_LOAD_PROC 8
+#define V_DEF_RES   9
+#define V_DEBUG_MEM 10
+#define V_SHOW_USE  11
+#define V_IMAP      12
+#define V_PROMPT    13
+#define V_NSB       14
+#define V_CONTENTSB 15
+#define V_CANCELUNIT 16
+#define V_DEG_STOP  31
+
+
+#define OPT_PROT           0
+#define OPT_REDSB          1
+#define OPT_NOT_BUCKETS    2
+#define OPT_NOT_SUGAR      3
+#define OPT_INTERRUPT      4
+#define OPT_SUGARCRIT      5
+#define OPT_DEBUG          6
+#define OPT_REDTHROUGH     7
+#define OPT_RETURN_SB      9
+#define OPT_FASTHC        10
+#define OPT_OLDSTD        20
+#define OPT_KEEPVARS      21
+#define OPT_STAIRCASEBOUND 22
+#define OPT_MULTBOUND     23
+#define OPT_DEGBOUND      24
+#define OPT_REDTAIL       25
+#define OPT_INTSTRATEGY   26
+#define OPT_INFREDTAIL    28
+#define OPT_SB_1          29
+#define OPT_NOTREGULARITY 30
+#define OPT_WEIGHTM       31
+
+/* define ring dependent options */
+#define TEST_RINGDEP_OPTS \
+ (Sy_bit(OPT_INTSTRATEGY) | Sy_bit(OPT_REDTHROUGH) | Sy_bit(OPT_REDTAIL))
+
+#define TEST_OPT_PROT              BTEST1(OPT_PROT)
+#define TEST_OPT_REDSB             BTEST1(OPT_REDSB)
+#define TEST_OPT_NOT_BUCKETS       BTEST1(OPT_NOT_BUCKETS)
+#define TEST_OPT_NOT_SUGAR         BTEST1(OPT_NOT_SUGAR)
+#define TEST_OPT_SUGARCRIT         BTEST1(OPT_SUGARCRIT)
+#define TEST_OPT_DEBUG             BTEST1(OPT_DEBUG)
+#define TEST_OPT_FASTHC            BTEST1(OPT_FASTHC)
+#define TEST_OPT_INTSTRATEGY       BTEST1(OPT_INTSTRATEGY)
+#define TEST_OPT_RETURN_SB         BTEST1(OPT_RETURN_SB)
+#define TEST_OPT_KEEPVARS          BTEST1(OPT_KEEPVARS)
+#define TEST_OPT_DEGBOUND          BTEST1(OPT_DEGBOUND)
+#define TEST_OPT_MULTBOUND         BTEST1(OPT_MULTBOUND)
+#define TEST_OPT_STAIRCASEBOUND    BTEST1(OPT_STAIRCASEBOUND)
+#define TEST_OPT_REDTAIL           BTEST1(OPT_REDTAIL)
+#define TEST_OPT_INFREDTAIL        BTEST1(OPT_INFREDTAIL)
+#define TEST_OPT_SB_1              BTEST1(OPT_SB_1)
+#define TEST_OPT_NOTREGULARITY     BTEST1(OPT_NOTREGULARITY)
+#define TEST_OPT_WEIGHTM           BTEST1(OPT_WEIGHTM)
+#define TEST_OPT_REDTHROUGH        BTEST1(OPT_REDTHROUGH)
+#define TEST_OPT_OLDSTD            BTEST1(OPT_OLDSTD)
+#define TEST_OPT_CONTENTSB         BVERBOSE(V_CONTENTSB)
+#define TEST_OPT_CANCELUNIT        BVERBOSE(V_CANCELUNIT)
+
+#define TEST_VERB_NSB              BVERBOSE(V_NSB)
+#define TEST_V_DEG_STOP            BVERBOSE(V_DEG_STOP)
+
+
+#ifdef HAVE_LIBPARSER
+#ifdef __cplusplus
+class libstack;
+typedef libstack *  libstackv;
+#endif
+#endif /* HAVE_LIBPARSER */
+
+extern struct omBin_s* MP_INT_bin;
+extern struct omBin_s* char_ptr_bin;
+extern struct omBin_s* ideal_bin;
+extern struct omBin_s* int_bin;
+extern struct omBin_s* poly_bin;
+extern struct omBin_s* void_ptr_bin;
+extern struct omBin_s* indlist_bin;
+extern struct omBin_s* naIdeal_bin;
+extern struct omBin_s* snaIdeal_bin;
+extern struct omBin_s* sm_prec_bin;
+extern struct omBin_s* smprec_bin;
+extern struct omBin_s* sip_sideal_bin;
+extern struct omBin_s* sip_smap_bin;
+extern struct omBin_s* sip_sring_bin;
+extern struct omBin_s* ip_sideal_bin;
+extern struct omBin_s* ip_smap_bin;
+extern struct omBin_s* ip_sring_bin;
+extern struct omBin_s* sleftv_bin;
+
+#ifdef __cplusplus
+union uutypes
+{
+  int           i;
+  ring          uring;
+  poly          p;
+  number        n;
+  ideal         uideal;
+  map           umap;
+  matrix        umatrix;
+  char *        ustring;
+  intvec *      iv;
+  lists         l;
+  si_link       li;
+  package       pack;
+  procinfo *    pinf;
+};
+
+class idrec
+{
+  public:
+  /* !! do not change the first 6 entries !! (see subexpr.h: sleftv) */
+  idhdl      next;
+  char *     id;
+  utypes     data;
+  attr       attribute;
+  BITSET     flag;
+  idtyp      typ;
+
+  short      lev;
+  short      ref;
+
+#define IDNEXT(a)    ((a)->next)
+#define IDTYP(a)     ((a)->typ)
+#define IDFLAG(a)    ((a)->flag)
+#define IDLEV(a)     ((a)->lev)
+#define IDID(a)      ((a)->id)
+#define IDATTR(a)    ((a)->attribute)
+
+#define IDINT(a)    ((a)->data.i)
+#define IDDATA(a)   ((a)->data.ustring)
+#define IDRING(a)   ((a)->data.uring)
+#define IDINTVEC(a) ((a)->data.iv)
+#define IDPOLY(a)   ((a)->data.p)
+#define IDNUMBER(a) ((a)->data.n)
+#define IDIDEAL(a)  (((a)->data).uideal)
+#define IDMATRIX(a) (((a)->data).umatrix)
+#define IDMAP(a)    (((a)->data).umap)
+#define IDSTRING(a) ((a)->data.ustring)
+#define IDLIST(a)   ((a)->data.l)
+#define IDLINK(a)   ((a)->data.li)
+#define IDPACKAGE(a) ((a)->data.pack)
+#define IDPROC(a)   ((a)->data.pinf)
+
+  idrec() { memset(this,0,sizeof(*this)); }
+  idhdl get(const char * s, int lev);
+  idhdl set(char * s, int lev, idtyp t, BOOLEAN init=TRUE);
+  char * String();
+//  ~idrec();
+};
+#endif
+
+#endif
+
Index: kernel/stype.h
===================================================================
--- kernel/stype.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/stype.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,24 @@
+#ifndef STYPE_H
+#define STYPE_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: stype.h,v 1.1.1.1 2003-10-06 12:15:55 Singular Exp $ */
+/*
+* ABSTRACT: flex/bison interface
+*/
+
+#include "structs.h"
+
+typedef union
+{
+  int       i;
+  char    * name;
+  sleftv    lv;
+} MYYSTYPE;
+#define YYSTYPE MYYSTYPE
+extern YYSTYPE  yylval;
+
+int yylex(MYYSTYPE *l);
+
+#endif
Index: kernel/syz.cc
===================================================================
--- kernel/syz.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/syz.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1082 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: syz.cc,v 1.1.1.1 2003-10-06 12:15:54 Singular Exp $ */
+
+/*
+* ABSTRACT: resolutions
+*/
+
+
+#include "mod2.h"
+#include "structs.h"
+#include "omalloc.h"
+#include "polys.h"
+#include "febase.h"
+#include "kstd1.h"
+#include "kutil.h"
+#include "stairc.h"
+#include "intvec.h"
+#include "numbers.h"
+#include "ideals.h"
+#include "intvec.h"
+#include "ring.h"
+#include "syz.h"
+#include "prCopy.h"
+
+
+void syDeleteRes(resolvente * res,int length)
+{
+  for (int i=0;i<length;i++)
+  {
+    if (!idIs0((*res)[i]))
+      idDelete(&((*res)[i]));
+  }
+  omFreeSize((ADDRESS)res,length*sizeof(ideal));
+  *res = NULL;
+}
+
+static intvec * syPrepareModComp(ideal arg,intvec ** w)
+{
+  intvec *w1 = NULL;
+  int i;
+  BOOLEAN isIdeal=FALSE;
+
+  if ((w==NULL) || (*w==NULL)) return w1;
+  int maxxx = (*w)->length();
+  if (maxxx==1)
+  {
+    maxxx = 2;
+    isIdeal = TRUE;
+  }
+  w1 = new intvec(maxxx+IDELEMS(arg));
+  if (!isIdeal)
+  {
+    for (i=0;i<maxxx;i++)
+    {
+      (*w1)[i] = (**w)[i];
+    }
+  }
+  for (i=maxxx;i<maxxx+IDELEMS(arg);i++)
+  {
+    if (arg->m[i-maxxx]!=NULL)
+    {
+      (*w1)[i] = pFDeg(arg->m[i-maxxx]);
+      if (pGetComp(arg->m[i-maxxx])!=0)
+      {
+        (*w1)[i]+=(**w)[pGetComp(arg->m[i-maxxx])-1];
+      }
+    }
+  }
+  delete (*w);
+  *w = new intvec(IDELEMS(arg)+1);
+  for (i=0;i<IDELEMS(arg);i++)
+  {
+     (**w)[i+1] = (*w1)[i+maxxx];
+  }
+  return w1;
+}
+
+static void syDeleteAbove(ideal up, int k)
+{
+  if (up!=NULL)
+  {
+    for (int i=0;i<IDELEMS(up);i++)
+    {
+      if (up->m[i]!=NULL)
+        pDeleteComp(&(up->m[i]),k+1);
+    }
+  }
+}
+
+/*2
+*minimizes the module mod and cancel superfluous syzygies
+*from syz
+*/
+static void syMinStep(ideal mod,ideal syz,BOOLEAN final=FALSE,ideal up=NULL,
+                      tHomog h=isNotHomog)
+{
+  ideal deg0=NULL;
+  poly Unit1,Unit2,actWith;
+  int len,i,j,ModComp,m,k,l;
+  BOOLEAN searchUnit,existsUnit;
+
+  if (TEST_OPT_PROT) PrintS("m");
+  if ((final) && (h==isHomog))
+  /*minim is TRUE, we are in the module: maxlength, maxlength <>0*/
+  {
+    deg0=idJet(syz,0);
+    idSkipZeroes(deg0);
+    syz=deg0;
+  }
+/*--cancels empty entees and their related components above--*/
+  j = IDELEMS(syz);
+  while ((j>0) && (!syz->m[j-1])) j--;
+  k = 0;
+  while (k<j)
+  {
+    if (syz->m[k]!=NULL)
+      k++;
+    else
+    {
+      if (TEST_OPT_PROT) PrintS(".");
+      for (l=k;l<j-1;l++) syz->m[l] = syz->m[l+1];
+      syz->m[j-1] = NULL;
+      syDeleteAbove(up,k);
+      j--;
+    }
+  }
+/*--searches for syzygies coming from superfluous elements
+* in the module below--*/
+  searchUnit = TRUE;
+  int curr_syz_limit = rGetCurrSyzLimit();
+  while (searchUnit)
+  {
+    i=0;
+    j=IDELEMS(syz);
+    while ((j>0) && (syz->m[j-1]==NULL)) j--;
+    existsUnit = FALSE;
+    if (currRing->OrdSgn == 1)
+    {
+      while ((i<j) && (!existsUnit))
+      {
+        existsUnit = pVectorHasUnitB(syz->m[i],&ModComp);
+        i++;
+      }
+    }
+    else
+    {
+      int I=0;
+      l = 0;
+      len=0;
+      for (i=0;i<IDELEMS(syz);i++)
+      {
+        if (syz->m[i]!=NULL)
+        {
+          pVectorHasUnit(syz->m[i],&m, &l);
+          if ((len==0) ||((l>0) && (l<len)))
+          {
+            len = l;
+            ModComp = m;
+            I = i;
+          }
+        }
+      }
+//Print("Laenge ist: %d\n",len);
+      if (len>0) existsUnit = TRUE;
+      i = I+1;
+    }
+    if (existsUnit)
+    {
+      i--;
+//--takes out the founded syzygy--
+      if (TEST_OPT_PROT) PrintS("f");
+      actWith = syz->m[i];
+      if (!rField_has_simple_inverse()) pCleardenom(actWith);
+//Print("actWith: ");pWrite(actWith);
+      syz->m[i] = NULL;
+      for (k=i;k<j-1;k++)  syz->m[k] = syz->m[k+1];
+      syz->m[j-1] = NULL;
+      syDeleteAbove(up,i);
+      j--;
+//--makes Gauss alg. for the column ModComp--
+      Unit1 = pTakeOutComp(&(actWith), ModComp);
+//PrintS("actWith now: ");pWrite(actWith);
+//Print("Unit1: ");pWrite(Unit1);
+      k=0;
+//Print("j= %d",j);
+      while (k<j)
+      {
+        if (syz->m[k]!=NULL)
+        {
+          Unit2 = pTakeOutComp(&(syz->m[k]), ModComp);
+//Print("element %d: ",k);pWrite(syz->m[k]);
+//PrintS("Unit2: ");pWrite(Unit2);
+          syz->m[k] = pMult(syz->m[k],pCopy(Unit1));
+          syz->m[k] = pSub(syz->m[k],
+            pMult(Unit2,pCopy(actWith)));
+          if (syz->m[k]==NULL)
+          {
+            for (l=k;l<j-1;l++)
+              syz->m[l] = syz->m[l+1];
+            syz->m[j-1] = NULL;
+            j--;
+            syDeleteAbove(up,k);
+            k--;
+          }
+        }
+        k++;
+      }
+      pDelete(&actWith);
+      pDelete(&Unit1);
+//--deletes superfluous elements from the module below---
+      pDelete(&(mod->m[ModComp-1 - curr_syz_limit]));
+      for (k=ModComp-1 - curr_syz_limit;k<IDELEMS(mod)-1;k++)
+        mod->m[k] = mod->m[k+1];
+      mod->m[IDELEMS(mod)-1] = NULL;
+    }
+    else
+      searchUnit = FALSE;
+  }
+  if (TEST_OPT_PROT) PrintLn();
+  idSkipZeroes(mod);
+  idSkipZeroes(syz);
+  if (deg0!=NULL)
+    idDelete(&deg0);
+}
+
+/*2
+* make Gauss with the element elnum in the module component ModComp
+* for the generators from - till
+*/
+void syGaussForOne(ideal syz, int elnum, int ModComp,int from,int till)
+{
+  int k,j,i,lu;
+  poly unit1,unit2;
+  poly actWith=syz->m[elnum];
+
+  if (from<0) from = 0;
+  if ((till<=0) || (till>IDELEMS(syz))) till = IDELEMS(syz);
+  syz->m[elnum] = NULL;
+  if (!rField_has_simple_inverse()) pCleardenom(actWith);
+/*--makes Gauss alg. for the column ModComp--*/
+  pTakeOutComp(&(actWith), ModComp, &unit1, &lu);
+  while (from<till)
+  {
+    if (syz->m[from]!=NULL)
+    {
+      pTakeOutComp(&(syz->m[from]), ModComp, &unit2, &lu);
+      syz->m[from] = pMult(syz->m[from],pCopy(unit1));
+      syz->m[from] = pSub(syz->m[from],
+        pMult(pCopy(actWith),unit2));
+    }
+    from++;
+  }
+  pDelete(&actWith);
+  pDelete(&unit1);
+}
+static void syDeleteAbove1(ideal up, int k)
+{
+  poly p,pp;
+  if (up!=NULL)
+  {
+    for (int i=0;i<IDELEMS(up);i++)
+    {
+      p = up->m[i];
+      while ((p!=NULL) && (pGetComp(p)==k))
+      {
+        pp = pNext(p);
+        pNext(p) = NULL;
+        pDelete(&p);
+        p = pp;
+      }
+      up->m[i] = p;
+      if (p!=NULL)
+      {
+        while (pNext(p)!=NULL)
+        {
+          if (pGetComp(pNext(p))==k)
+          {
+            pp = pNext(pNext(p));
+            pNext(pNext(p)) = NULL;
+            pDelete(&pNext(p));
+            pNext(p) = pp;
+          }
+          else
+            pIter(p);
+        }
+      }
+    }
+  }
+}
+/*2
+*minimizes the resolution res
+*assumes homogeneous or local case
+*/
+static void syMinStep1(resolvente res, int length)
+{
+  int i,j,k,l,index=0;
+  poly p;
+  ideal deg0=NULL,reddeg0=NULL;
+  intvec *have_del=NULL,*to_del=NULL;
+
+  while ((index<length) && (res[index]!=NULL))
+  {
+/*---we take out dependend elements from syz---------------------*/
+    if (res[index+1]!=NULL)
+    {
+      deg0 = idJet(res[index+1],0);
+      reddeg0 = kInterRed(deg0);
+      idDelete(&deg0);
+      have_del = new intvec(IDELEMS(res[index]));
+      for (i=0;i<IDELEMS(reddeg0);i++)
+      {
+        if (reddeg0->m[i]!=NULL)
+        {
+          j = pGetComp(reddeg0->m[i]);
+          pDelete(&(res[index]->m[j-1]));
+          res[index]->m[j-1] = NULL;
+          (*have_del)[j-1] = 1;
+        }
+      }
+      idDelete(&reddeg0);
+    }
+    if (index>0)
+    {
+/*--- we search for units and perform Gaussian elimination------*/
+      j = to_del->length();
+      while (j>0)
+      {
+        if ((*to_del)[j-1]==1)
+        {
+          k = 0;
+          while (k<IDELEMS(res[index]))
+          {
+            p = res[index]->m[k];
+            while ((p!=NULL) && ((!pLmIsConstantComp(p)) || (pGetComp(p)!=j)))
+              pIter(p);
+            if ((p!=NULL) && (pLmIsConstantComp(p)) && (pGetComp(p)==j)) break;
+            k++;
+          }
+          if (k>=IDELEMS(res[index]))
+          {
+            PrintS("out of range\n");
+          }
+          syGaussForOne(res[index],k,j);
+          if (res[index+1]!=NULL)
+            syDeleteAbove1(res[index+1],k+1);
+          (*to_del)[j-1] = 0;
+        }
+        j--;
+      }
+    }
+    if (to_del!=NULL) delete to_del;
+    to_del = have_del;
+    have_del = NULL;
+    index++;
+  }
+  if (TEST_OPT_PROT) PrintLn();
+  syKillEmptyEntres(res,length);
+}
+
+void syMinimizeResolvente(resolvente res, int length, int first)
+{
+  int syzIndex=first;
+  intvec *dummy;
+
+  if (syzIndex<1) syzIndex=1;
+  if ((syzIndex==1) && (idHomModule(res[0],currQuotient,&dummy)) && (!rIsPluralRing(currRing)))
+  {
+    syMinStep1(res,length);
+    delete dummy;
+    return;
+  }
+  while ((syzIndex<length-1) && (res[syzIndex]!=NULL) && (res[syzIndex+1]!=NULL))
+  {
+    syMinStep(res[syzIndex-1],res[syzIndex],FALSE,res[syzIndex+1]);
+    syzIndex++;
+  }
+  if (res[syzIndex]!=NULL)
+    syMinStep(res[syzIndex-1],res[syzIndex]);
+  if (!idIs0(res[0]))
+    idMinEmbedding(res[0],TRUE);
+}
+
+/*2
+* resolution of ideal/module arg, <=maxlength steps, (r[0..maxlength])
+*   no limitation in length if maxlength==0
+* input:arg
+*       minim: TRUE means mres cmd, FALSE nres cmd.
+*       if *len!=0: module weights: weights[0]
+*          (and weights is defined:weights[0..len-1]
+*
+* output:resolvente r[0..length-1],
+*        module weights: weights[0..length-1]
+*/
+resolvente syResolvente(ideal arg, int maxlength, int * length,
+                        intvec *** weights, BOOLEAN minim)
+{
+  resolvente res;
+  resolvente newres;
+  tHomog hom=isNotHomog;
+  ideal temp=NULL;
+  intvec *w = NULL,**tempW;
+  int i,k,syzIndex = 0,j,rk_arg=si_max(1,idRankFreeModule(arg));
+  int Kstd1_OldDeg=Kstd1_deg;
+  BOOLEAN completeMinim;
+  BOOLEAN oldDegBound=TEST_OPT_DEGBOUND;
+  BOOLEAN setRegularity=TRUE;
+  int wlength=*length;
+
+  if (maxlength!=-1) *length = maxlength+1;
+  else              *length = 5;
+  if ((wlength!=0) && (*length!=wlength))
+  {
+    intvec **wtmp = (intvec**)omAlloc0((*length)*sizeof(intvec*));
+    wtmp[0]=(*weights)[0];
+    omFreeSize((ADDRESS)*weights,wlength*sizeof(intvec*));
+    *weights=wtmp;
+  }
+  res = (resolvente)omAlloc0((*length)*sizeof(ideal));
+
+/*--- initialize the syzygy-ring -----------------------------*/
+  ring origR = currRing;
+  ring syz_ring = rCurrRingAssure_SyzComp();
+  rSetSyzComp(rk_arg);
+
+  if (syz_ring != origR)
+  {
+    res[0] = idrCopyR_NoSort(arg, origR);
+  }
+  else
+  {
+    res[0] = idCopy(arg);
+  }
+
+/*--- creating weights for the module components ---------------*/
+  if ((weights==NULL) || (*weights==NULL) || ((*weights)[0]==NULL))
+  {
+    hom=(tHomog)idHomModule(res[0],currQuotient,&w);
+    if (hom==isHomog)
+    {
+      *weights = (intvec**)omAlloc0((*length)*sizeof(intvec*));
+      if (w!=NULL) (*weights)[0] = ivCopy(w);
+    }
+  }
+  else
+  {
+    if ((weights!=NULL) && (*weights!=NULL)&& ((*weights)[0]!=NULL))
+    {
+      w = ivCopy((*weights)[0]);
+      hom = isHomog;
+    }
+  }
+  if (hom==isHomog)
+  {
+    intvec *w1 = syPrepareModComp(res[0],&w);
+    if (w!=NULL) { delete w;w=NULL; }
+    w = w1;
+    j = 0;
+    while ((j<IDELEMS(res[0])) && (res[0]->m[j]==NULL)) j++;
+    if (j<IDELEMS(res[0]))
+    {
+      if (pFDeg(res[0]->m[j])!=pTotaldegree(res[0]->m[j]))
+        setRegularity = FALSE;
+    }
+  }
+  else
+  {
+    setRegularity = FALSE;
+  }
+
+/*--- the main loop --------------------------------------*/
+  while ((!idIs0(res[syzIndex])) &&
+         ((maxlength==-1) || (syzIndex<=maxlength)))
+   // (syzIndex<maxlength+(int)minim)))
+/*--- compute one step more for minimizing-----------------*/
+  {
+    if (Kstd1_deg!=0) Kstd1_deg++;
+    if (syzIndex+1==*length)
+    {
+      newres = (resolvente)omAlloc0((*length+5)*sizeof(ideal));
+      tempW = (intvec**)omAlloc0((*length+5)*sizeof(intvec*));
+      for (j=0;j<*length;j++)
+      {
+        newres[j] = res[j];
+        if (*weights!=NULL) tempW[j] = (*weights)[j];
+        /*else              tempW[j] = NULL;*/
+      }
+      omFreeSize((ADDRESS)res,*length*sizeof(ideal));
+      if (*weights != NULL) omFreeSize((ADDRESS)*weights,*length*sizeof(intvec*));
+      *length += 5;
+      res=newres;
+      *weights = tempW;
+    }
+/*--- interreducing first -----------------------------------*/
+    if (syzIndex>0)
+    {
+      int rkI=idRankFreeModule(res[syzIndex]);
+      rSetSyzComp(rkI);
+    }
+    if (minim || (syzIndex!=0))
+    {
+      temp = kInterRed(res[syzIndex],currQuotient);
+      idDelete(&res[syzIndex]);
+      idSkipZeroes(temp);
+      res[syzIndex] = temp;
+    }
+    temp = NULL;
+/*--- computing the syzygy modules --------------------------------*/
+    if ((currQuotient==NULL)&&(syzIndex==0)&& (!TEST_OPT_DEGBOUND))
+    {
+      res[/*syzIndex+*/1] = idSyzygies(res[0/*syzIndex*/],hom,&w,FALSE,setRegularity,&Kstd1_deg);
+      if ((!TEST_OPT_NOTREGULARITY) && (Kstd1_deg>0)) test |= Sy_bit(OPT_DEGBOUND);
+    }
+    else
+    {
+        res[syzIndex+1] = idSyzygies(res[syzIndex],hom,&w,FALSE);
+    }
+    completeMinim=(syzIndex!=maxlength) || (maxlength ==-1) || (hom!=isHomog);
+    syzIndex++;
+    if (TEST_OPT_PROT) Print("[%d]\n",syzIndex);
+    if ((minim)||(syzIndex>1))
+      syMinStep(res[syzIndex-1],res[syzIndex],!completeMinim,NULL,hom);
+    if (!completeMinim)
+    /*minim is TRUE, we are in the module: maxlength, maxlength <>0*/
+    {
+      idDelete(&res[syzIndex]);
+    }
+/*---creating the iterated weights for module components ---------*/
+    if ((hom == isHomog) && (!idIs0(res[syzIndex])))
+    {
+//Print("die %d Modulegewichte sind:\n",w1->length());
+//w1->show();
+//PrintLn();
+      int max_comp = idRankFreeModule(res[syzIndex]);
+      k = max_comp - rGetCurrSyzLimit();
+      assume(w != NULL);
+      if (w != NULL)
+        w->resize(max_comp+IDELEMS(res[syzIndex]));
+      else
+        w = new intvec(max_comp+IDELEMS(res[syzIndex]));
+      (*weights)[syzIndex] = new intvec(k);
+      for (i=0;i<k;i++)
+      {
+        if (res[syzIndex-1]->m[i]!=NULL) // hs
+        {
+          (*w)[i + rGetCurrSyzLimit()] = pFDeg(res[syzIndex-1]->m[i]);
+          if (pGetComp(res[syzIndex-1]->m[i])>0)
+            (*w)[i + rGetCurrSyzLimit()]
+              += (*w)[pGetComp(res[syzIndex-1]->m[i])-1];
+          (*((*weights)[syzIndex]))[i] = (*w)[i+rGetCurrSyzLimit()];
+        }
+      }
+      for (i=k;i<k+IDELEMS(res[syzIndex]);i++)
+      {
+        if (res[syzIndex]->m[i-k]!=NULL)
+          (*w)[i+rGetCurrSyzLimit()] = pFDeg(res[syzIndex]->m[i-k])
+                    +(*w)[pGetComp(res[syzIndex]->m[i-k])-1];
+      }
+    }
+  }
+/*--- end of the main loop --------------------------------------*/
+/*--- deleting the temporare data structures --------------------*/
+  if ((syzIndex!=0) && (res[syzIndex]!=NULL) && (idIs0(res[syzIndex])))
+    idDelete(&res[syzIndex]);
+  if (w !=NULL) delete w;
+
+  Kstd1_deg=Kstd1_OldDeg;
+  if (!oldDegBound)
+    test &= ~Sy_bit(OPT_DEGBOUND);
+
+  for (i=1; i<=syzIndex; i++)
+  {
+    if (! idIs0(res[i]))
+    {
+      for (j=0; j<IDELEMS(res[i]); j++)
+      {
+        pShift(&res[i]->m[j], -rGetMaxSyzComp(i));
+      }
+    }
+  }
+/*--- going back to the original ring -------------------------*/
+  if (origR != syz_ring)
+  {
+    rChangeCurrRing(origR);
+    for (i=0; i<=syzIndex; i++)
+    {
+      res[i] = idrMoveR_NoSort(res[i], syz_ring);
+    }
+    rKill(syz_ring);
+  }
+  return res;
+}
+
+syStrategy syResolution(ideal arg, int maxlength,intvec * w, BOOLEAN minim)
+{
+  int typ0;
+  syStrategy result=(syStrategy)omAlloc0(sizeof(ssyStrategy));
+
+  if (w!=NULL)
+  {
+    result->weights = (intvec**)omAlloc0Bin(void_ptr_bin);
+    (result->weights)[0] = ivCopy(w);
+    result->length = 1;
+  }
+  resolvente fr = syResolvente(arg,maxlength,&(result->length),&(result->weights),minim),fr1;
+  if (minim)
+  {
+    result->minres = (resolvente)omAlloc0((result->length+1)*sizeof(ideal));
+    fr1 =  result->minres;
+  }
+  else
+  {
+    result->fullres = (resolvente)omAlloc0((result->length+1)*sizeof(ideal));
+    fr1 =  result->fullres;
+  }
+  for (int i=result->length-1;i>=0;i--)
+  {
+    if (fr[i]!=NULL)
+      fr1[i] = fr[i];
+    fr[i] = NULL;
+  }
+  omFreeSize((ADDRESS)fr,(result->length)*sizeof(ideal));
+  return result;
+}
+
+static poly sypCopyConstant(poly inp)
+{
+  poly outp=NULL,q;
+
+  while (inp!=NULL)
+  {
+    if (pLmIsConstantComp(inp))
+    {
+      if (outp==NULL)
+      {
+        q = outp = pHead(inp);
+      }
+      else
+      {
+        pNext(q) = pHead(inp);
+        pIter(q);
+      }
+    }
+    pIter(inp);
+  }
+  return outp;
+}
+int syDetect(ideal id,int index,BOOLEAN homog,int * degrees,int * tocancel)
+{
+  int i, j, k, ModComp,subFromRank=0, lu;
+  poly p, q, qq, Unit1, Unit2;
+  ideal temp;
+
+  if (idIs0(id)) return 0;
+  temp = idInit(IDELEMS(id),id->rank);
+  for (i=0;i<IDELEMS(id);i++)
+  {
+    temp->m[i] = sypCopyConstant(id->m[i]);
+  }
+  i = IDELEMS(id);
+  while ((i>0) && (temp->m[i-1]==NULL)) i--;
+  if (i==0)
+  {
+    idDelete(&temp);
+    return 0;
+  }
+  j = 0;
+  p = NULL;
+  while ((j<i) && (temp->m[j]==NULL)) j++;
+  while (j<i)
+  {
+    if (homog)
+    {
+      k = pFDeg(id->m[j])+degrees[pGetComp(id->m[j])];
+      if (k>=index) tocancel[k-index]++;
+      if ((k>=0) && (index==0)) subFromRank++;
+    }
+    else
+    {
+      tocancel[0]--;
+    }
+    syGaussForOne(temp,j,pGetComp(temp->m[j]),j+1,i);
+    j++;
+    while ((j<i) && (temp->m[j]==NULL)) j++;
+  }
+  idDelete(&temp);
+  return subFromRank;
+}
+
+void syDetect(ideal id,int index,int rsmin, BOOLEAN homog,
+              intvec * degrees,intvec * tocancel)
+{
+  int * deg=NULL;
+  int * tocan=(int*) omAlloc0(tocancel->length()*sizeof(int));
+  int i;
+
+  if (homog)
+  {
+    deg = (int*) omAlloc0(degrees->length()*sizeof(int));
+    for (i=degrees->length();i>0;i--)
+      deg[i-1] = (*degrees)[i-1]-rsmin;
+  }
+  int dummy=syDetect(id,index,homog,deg,tocan);
+  for (i=tocancel->length();i>0;i--)
+    (*tocancel)[i-1] = tocan[i-1];
+  if (homog)
+    omFreeSize((ADDRESS)deg,degrees->length()*sizeof(int));
+  omFreeSize((ADDRESS)tocan,tocancel->length()*sizeof(int));
+}
+
+/*2
+* computes the betti numbers from a given resolution
+* of length 'length' (0..length-1), not necessairily minimal,
+* (if weights are given, they are used)
+* returns the int matrix of betti numbers
+* and the regularity
+*/
+intvec * syBetti(resolvente res,int length, int * regularity,
+                 intvec* weights,BOOLEAN tomin,int * row_shift)
+{
+//#define BETTI_WITH_ZEROS
+  //tomin = FALSE;
+  int i,j=0,k=0,l,rows,cols,mr;
+  int *temp1,*temp2,*temp3;/*used to compute degrees*/
+  int *tocancel; /*(BOOLEAN)tocancel[i]=element is superfluous*/
+  int r0_len;
+
+  /*------ compute size --------------*/
+  *regularity = -1;
+  cols = length;
+  while ((cols>0)
+  && ((res[cols-1]==NULL)
+    || (idIs0(res[cols-1]))))
+  {
+    cols--;
+  }
+  intvec * result;
+  if (idIs0(res[0]))
+  {
+    if (res[0]==NULL)
+      result = new intvec(1,1,1);
+    else
+      result = new intvec(1,1,res[0]->rank);
+    return result;
+  }
+  r0_len=IDELEMS(res[0]);
+  while ((r0_len>0) && (res[0]->m[r0_len-1]==NULL)) r0_len--;
+  intvec *w=NULL;
+  if (idHomModule(res[0],currQuotient,&w)!=isHomog)
+  {
+    Warn("betti-command: Input is not homogeneous!");
+  }
+  delete w;
+  int rkl=l = si_max(idRankFreeModule(res[0]),res[0]->rank);
+  i = 0;
+  while ((i<length) && (res[i]!=NULL))
+  {
+    if (IDELEMS(res[i])>l) l = IDELEMS(res[i]);
+    i++;
+  }
+  temp1 = (int*)omAlloc0((l+1)*sizeof(int));
+  temp2 = (int*)omAlloc((l+1)*sizeof(int));
+  rows = 1;
+  mr = 1;
+  cols++;
+  for (i=0;i<cols-1;i++)
+  {
+    if ((i==0) && (weights!=NULL)) pSetModDeg(weights);
+    memset(temp2,0,(l+1)*sizeof(int));
+    for (j=0;j<IDELEMS(res[i]);j++)
+    {
+      if (res[i]->m[j]!=NULL)
+      {
+        if ((pGetComp(res[i]->m[j])>l)
+        || ((i>1) && (res[i-1]->m[pGetComp(res[i]->m[j])-1]==NULL)))
+        {
+          WerrorS("input not a resolvent");
+          omFreeSize((ADDRESS)temp1,(l+1)*sizeof(int));
+          omFreeSize((ADDRESS)temp2,(l+1)*sizeof(int));
+          return NULL;
+        }
+        temp2[j+1] = pFDeg(res[i]->m[j])+temp1[pGetComp(res[i]->m[j])];
+        if (temp2[j+1]-i>rows) rows = temp2[j+1]-i;
+        if (temp2[j+1]-i<mr) mr = temp2[j+1]-i;
+      }
+    }
+    if ((i==0) && (weights!=NULL)) pSetModDeg(NULL);
+    temp3 = temp1;
+    temp1 = temp2;
+    temp2 = temp3;
+  }
+  mr--;
+  /*------ computation betti numbers --------------*/
+  rows -= mr;
+  result = new intvec(rows,cols,0);
+  (*result)[(-mr)*cols] = /*idRankFreeModule(res[0])*/ rkl;
+  if ((!idIs0(res[0])) && ((*result)[(-mr)*cols]==0))
+    (*result)[(-mr)*cols] = 1;
+  tocancel = (int*)omAlloc0((rows+1)*sizeof(int));
+  memset(temp2,0,l*sizeof(int));
+  memset(temp1,0,(l+1)*sizeof(int));
+  int dummy = syDetect(res[0],0,TRUE,temp2,tocancel);
+  if (tomin)
+    (*result)[(-mr)*cols] -= dummy;
+  for (i=0;i<cols-1;i++)
+  {
+    if ((i==0) && (weights!=NULL)) pSetModDeg(weights);
+    memset(temp2,0,l*sizeof(int));
+    for (j=0;j<IDELEMS(res[i]);j++)
+    {
+      if (res[i]->m[j]!=NULL)
+      {
+        temp2[j+1] = pFDeg(res[i]->m[j])+temp1[pGetComp(res[i]->m[j])];
+        //(*result)[i+1+(temp2[j+1]-i-1)*cols]++;
+        //if (temp2[j+1]>i) IMATELEM((*result),temp2[j+1]-i-mr,i+2)++;
+        IMATELEM((*result),temp2[j+1]-i-mr,i+2)++;
+      }
+      else if (i==0)
+      {
+        if (j<r0_len) IMATELEM((*result),-mr,2)++;
+      }
+    }
+  /*------ computation betti numbers, if res not minimal --------------*/
+    if (tomin)
+    {
+      for (j=mr;j<rows+mr;j++)
+      {
+        //(*result)[i+1+j*cols] -= tocancel[j+1];
+        IMATELEM((*result),j+1-mr,i+2) -= tocancel[j+1];
+      }
+      if ((i<length-1) && (res[i+1]!=NULL))
+      {
+        memset(tocancel,0,(rows+1)*sizeof(int));
+        dummy = syDetect(res[i+1],i+1,TRUE,temp2,tocancel);
+        for (j=0;j<rows;j++)
+        {
+          //(*result)[i+1+j*cols] -= tocancel[j];
+          IMATELEM((*result),j+1,i+2) -= tocancel[j];
+        }
+      }
+    }
+    temp3 = temp1;
+    temp1 = temp2;
+    temp2 = temp3;
+    for (j=0;j<rows;j++)
+    {
+    //  if (((*result)[i+1+j*cols]!=0) && (j>*regularity)) *regularity = j;
+      if ((IMATELEM((*result),j+1,i+2)!=0) && (j>*regularity)) *regularity = j;
+    }
+    if ((i==0) && (weights!=NULL)) pSetModDeg(NULL);
+  }
+  /*------ clean up --------------*/
+  omFreeSize((ADDRESS)tocancel,(rows+1)*sizeof(int));
+  omFreeSize((ADDRESS)temp1,(l+1)*sizeof(int));
+  omFreeSize((ADDRESS)temp2,(l+1)*sizeof(int));
+  if ((tomin) && (mr<0))  // deletes the first (zero) line
+  {
+    for (j=1;j<=rows+mr;j++)
+    {
+      for (k=1;k<=cols;k++)
+      {
+        IMATELEM((*result),j,k) = IMATELEM((*result),j-mr,k);
+      }
+    }
+    for (j=rows+mr+1;j<=rows;j++)
+    {
+      for (k=1;k<=cols;k++)
+      {
+        IMATELEM((*result),j,k) = 0;
+      }
+    }
+  }
+  j = 0;
+  k = 0;
+  for (i=0;i<rows*cols;i++)
+  {
+    if ((*result)[i] != 0)
+    {
+      if (i/cols>j) j = i/cols;
+      if (i>k+(i/cols)*cols) k = i-(i/cols)*cols;
+    }
+  }
+  intvec * exactresult=new intvec(j+1,k+1,0);
+  for (i=0;i<exactresult->rows();i++)
+  {
+    for (j=0;j<exactresult->cols();j++)
+    {
+      IMATELEM(*exactresult,i+1,j+1) = IMATELEM(*result,i+1,j+1);
+    }
+  }
+  if (row_shift!=NULL) *row_shift = mr;
+  delete result;
+  return exactresult;
+}
+
+/*2
+* minbare via syzygies
+*/
+ideal syMinBase(ideal arg)
+{
+  intvec ** weights=NULL;
+  int leng;
+  if (idIs0(arg)) return idInit(1,arg->rank);
+  resolvente res=syResolvente(arg,1,&leng,&weights,TRUE);
+  ideal result=res[0];
+  omFreeSize((ADDRESS)res,leng*sizeof(ideal));
+  if (weights!=NULL)
+  {
+    if (*weights!=NULL)
+    {
+      delete (*weights);
+      *weights=NULL;
+    }
+    if ((leng>=1) && (*(weights+1)!=NULL))
+    {
+      delete *(weights+1);
+      *(weights+1)=NULL;
+    }
+  }
+  idSkipZeroes(result);
+  return result;
+}
+
+/*2
+* computes Betti-numbers from a resolvente of
+* (non-)homogeneous objects
+* the numbers of entrees !=NULL in res and weights must be equal
+* and < length
+*/
+intvec * syNewBetti(resolvente res, intvec ** weights, int length)
+{
+  intvec * result,*tocancel;
+  int i,j,k,rsmin=0,rsmax=0,rs=0;
+  BOOLEAN homog=TRUE;
+
+  if (weights!=NULL)           //---homogeneous Betti numbers
+  {
+/*--------------computes size of the field----------------------*/
+    for (i=1;i<length;i++)
+    {
+      if (weights[i] != NULL)
+      {
+        for (j=1;j<(weights[i])->length();j++)
+        {
+          if ((*(weights[i]))[j]-i<rsmin) rsmin = (*(weights[i]))[j]-i;
+          if ((*(weights[i]))[j]-i>rsmax) rsmax = (*(weights[i]))[j]-i;
+        }
+      }
+    }
+    i = 0;
+    while (weights[i] != NULL) i++;
+    i--;
+    for (j=0;j<IDELEMS(res[i]);j++)
+    {
+      if (res[i]->m[j]!=NULL)
+      {
+        k = pFDeg(res[i]->m[j])+(*(weights[i]))[pGetComp(res[i]->m[j])]-i-1;
+        if (k>rsmax) rsmax = k;
+        if (k<rsmin) rsmin = k;
+      }
+    }
+    for (j=1;j<(weights[0])->length();j++)
+    {
+      if ((*weights[0])[j]>rsmax) rsmax = (*weights[0])[j];
+      if ((*weights[0])[j]<rsmin) rsmin = (*weights[0])[j];
+    }
+//Print("rsmax = %d\n",rsmax);
+//Print("rsmin = %d\n",rsmin);
+    rs = rsmax-rsmin+1;
+    result = new intvec(rs,i+2,0);
+    tocancel = new intvec(rs);
+/*-----------enter the Betti numbers-------------------------------*/
+    if (/*idRankFreeModule(res[0])*/ res[0]->rank==0)
+    {
+      IMATELEM(*result,1-rsmin,1)=1;
+    }
+    else
+    {
+      for (i=1;i<(weights[0])->length();i++)
+        IMATELEM(*result,(*weights[0])[i]+1-rsmin,1)++;
+    }
+    i = 1;
+    while (weights[i]!=NULL)
+    {
+      for (j=1;j<(weights[i])->length();j++)
+      {
+        IMATELEM(*result,(*(weights[i]))[j]-i+1-rsmin,i+1)++;
+      }
+      i++;
+    }
+    i--;
+    for (j=0;j<IDELEMS(res[i]);j++)
+    {
+      if (res[i]->m[j]!=NULL)
+      {
+        k = pFDeg(res[i]->m[j])+(*(weights[i]))[pGetComp(res[i]->m[j])]-i;
+        IMATELEM(*result,k-rsmin,i+2)++;
+      }
+    }
+  }
+  else                //-----the non-homgeneous case
+  {
+    homog = FALSE;
+    tocancel = new intvec(1);
+    k = length;
+    while ((k>0) && (idIs0(res[k-1]))) k--;
+    result = new intvec(1,k+1,0);
+    (*result)[0] = res[0]->rank;
+    for (i=0;i<length;i++)
+    {
+      if (res[i]!=NULL)
+      {
+        for (j=0;j<IDELEMS(res[i]);j++)
+        {
+          if (res[i]->m[j]!=NULL) (*result)[i+1]++;
+        }
+      }
+    }
+  }
+/*--------computes the Betti numbers for the minimized reolvente----*/
+
+  i = 1;
+  while ((res[i]!=NULL) && (weights[i]!=NULL))
+  {
+    syDetect(res[i],i,rsmin,homog,weights[i],tocancel);
+    if (homog)
+    {
+      for (j=0;j<rs-1;j++)
+      {
+        IMATELEM((*result),j+1,i+1) -= (*tocancel)[j];
+        IMATELEM((*result),j+1,i+2) -= (*tocancel)[j+1];
+      }
+      IMATELEM((*result),rs,i+1) -= (*tocancel)[rs-1];
+    }
+    else
+    {
+      (*result)[i+1] -= (*tocancel)[0];
+      (*result)[i+2] -= (*tocancel)[0];
+    }
+    i++;
+  }
+
+/*--------print Betti numbers for control---------------------------*/
+  for(i=rsmin;i<=rsmax;i++)
+  {
+    Print("%2d:",i);
+    for(j=1;j<=result->cols();j++)
+    {
+      Print(" %5d",IMATELEM(*result,i-rsmin+1,j));
+    }
+    PrintLn();
+  }
+  return result;
+}
+
+/*2
+* is looking for the minimal minimized module of a resolvente
+* i.e. returns 0 if res comes from a mres-command and 1 in the
+* case of res-commands
+*/
+int syIsMinimizedFrom(resolvente res,int length)
+{
+  poly p;
+  int i,j=length;
+
+  while ((j>0) && (res[j-1]==NULL)) j--;
+  while (j>0)
+  {
+    for (i=0;i<IDELEMS(res[j-1]);i++)
+    {
+      p = res[j-1]->m[i];
+      while (p!=NULL)
+      {
+        if (pLmIsConstantComp(p)) return j;
+        p = pNext(p);
+      }
+    }
+    j--;
+  }
+  return j;
+}
Index: kernel/syz.h
===================================================================
--- kernel/syz.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/syz.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,139 @@
+#ifndef SYZ_H
+#define SYZ_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: syz.h,v 1.1.1.1 2003-10-06 12:15:54 Singular Exp $ */
+/*
+* ABSTRACT: Resolutions
+*/
+#include "structs.h"
+
+// Logarithm of estimate of maximal number of new components
+#define SYZ_SHIFT_MAX_NEW_COMP_ESTIMATE 8
+// Logarithm of "distance" between a new component and prev component
+#define SYZ_SHIFT_BASE_LOG (BIT_SIZEOF_LONG - 1 - SYZ_SHIFT_MAX_NEW_COMP_ESTIMATE)
+#define SYZ_SHIFT_BASE (((long)1) << SYZ_SHIFT_BASE_LOG)
+struct sSObject{
+                 poly  p;
+                 poly  p1,p2; /*- the pair p comes from -*/
+                 poly  lcm;   /*- the lcm of p1,p2 -*/
+                 poly  syz;   /*- the syzygy associated to p1,p2 -*/
+                 int   ind1,ind2; /*- the indeces of p1,p2 -*/
+                 poly  isNotMinimal;
+                 int   syzind;
+                 int   order;
+                 int   length;
+                 int   reference;
+               };
+typedef struct sSObject SObject;
+typedef SObject * SSet;
+typedef SSet * SRes;
+
+class ssyStrategy;
+typedef ssyStrategy * syStrategy;
+class ssyStrategy{
+  public:
+  int ** truecomponents;
+  long** ShiftedComponents;
+  int ** backcomponents;
+  int ** Howmuch;
+  int ** Firstelem;
+  int ** elemLength;
+  intvec ** weights;
+  intvec ** hilb_coeffs;
+  resolvente res;              //polynomial data for internal use only
+  resolvente orderedRes;       //polynomial data for internal use only
+  SRes resPairs;               //polynomial data for internal use only
+  intvec * Tl;
+  intvec * resolution;
+  intvec * cw;
+  intvec * betti;
+  kBucket_pt bucket;
+  kBucket_pt syz_bucket;
+  ring syRing;
+  resolvente fullres;
+  resolvente minres;
+  unsigned long ** sev;
+  int length;
+  int regularity;
+  short list_length;
+  short references;
+};
+
+void sySchreyersSyzygiesM(polyset F,int Fmax,polyset* Shdl,int* Smax,
+   BOOLEAN noSort);
+
+void sySchreyersSyzygiesB(polyset F,int Fmax,polyset* Shdl,int* Smax,
+   BOOLEAN noSort);
+
+resolvente sySchreyerResolvente(ideal arg, int maxlength, int * length,
+   BOOLEAN isMonomial=FALSE, BOOLEAN notReplace=FALSE);
+
+syStrategy sySchreyer(ideal arg, int maxlength);
+
+resolvente syResolvente(ideal arg, int maxlength, int * length,
+                        intvec *** weights, BOOLEAN minim);
+
+resolvente syReorder(resolvente res,int length,
+        syStrategy syzstr,BOOLEAN toCopy/*=TRUE*/,resolvente totake/*=NULL*/);
+
+syStrategy syResolution(ideal arg, int maxlength,intvec * w, BOOLEAN minim);
+
+void syMinimizeResolvente(resolvente res, int length, int first);
+
+intvec * syBetti(resolvente res,int length, int * regularity,
+         intvec* weights=NULL,BOOLEAN tomin=TRUE, int * row_shift=NULL);
+
+ideal syMinBase(ideal arg);
+
+BOOLEAN syTestOrder(ideal i);
+
+void syReOrderResolventFB(resolvente res,int length, int initial=1);
+
+resolvente syLaScala1(ideal arg,int * length);
+syStrategy syLaScala3(ideal arg,int * length);
+syStrategy syHilb(ideal arg,int * length);
+syStrategy syKosz(ideal arg,int * length);
+
+void syDeleteRes(resolvente * res,int length);
+void syKillComputation(syStrategy syzstr, ring r=currRing);
+intvec * syBettiOfComputation(syStrategy syzstr, BOOLEAN minim=TRUE,int * row_shift=NULL);
+BOOLEAN syBetti1(leftv res, leftv u);
+BOOLEAN syBetti2(leftv res, leftv u, leftv w);
+int syLength(syStrategy syzstr);
+int sySize(syStrategy syzstr);
+int syDim(syStrategy syzstr);
+syStrategy syCopy(syStrategy syzstr);
+void syPrint(syStrategy syzstr);
+lists syConvRes(syStrategy syzstr,BOOLEAN toDel=FALSE);
+syStrategy syConvList(lists li,BOOLEAN toDel=FALSE);
+syStrategy syForceMin(lists li);
+syStrategy syMinimize(syStrategy syzstr);
+void syKillEmptyEntres(resolvente res,int length);
+
+extern int *  currcomponents;
+extern long *  currShiftedComponents;
+
+int syzcomp1dpc(poly p1, poly p2);
+void syDeletePair(SObject * so);
+void syInitializePair(SObject * so);
+void syCopyPair(SObject * argso, SObject * imso);
+void syCompactifyPairSet(SSet sPairs, int sPlength, int first);
+void syCompactify1(SSet sPairs, int* sPlength, int first);
+SRes syInitRes(ideal arg,int * length, intvec * Tl, intvec * cw=NULL);
+void syResetShiftedComponents(syStrategy syzstr, int index,int hilb=0);
+void syEnlargeFields(syStrategy syzstr,int index);
+void syEnterPair(syStrategy syzstr, SObject * so, int * sPlength,int index);
+SSet syChosePairs(syStrategy syzstr, int *index, int *howmuch, int * actdeg);
+int syInitSyzMod(syStrategy syzstr, int index, int init=17);
+long syReorderShiftedComponents(long * sc, int n);
+void syGaussForOne(ideal arg,int gen,int ModComp,int from=-1,int till=0);
+void syEnterPair(SSet sPairs, SObject * so, int * sPlength,int index);
+void syEnterPair(syStrategy syzstr, SObject * so, int * sPlength,int index);
+syStrategy syKosz(ideal arg,int * length);
+
+resolvente syReorder(resolvente res,int length,
+        syStrategy syzstr,BOOLEAN toCopy=TRUE,resolvente totake=NULL);
+
+#endif
Index: kernel/syz0.cc
===================================================================
--- kernel/syz0.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/syz0.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1025 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: syz0.cc,v 1.1.1.1 2003-10-06 12:16:04 Singular Exp $ */
+/*
+* ABSTRACT: resolutions
+*/
+
+
+#include "mod2.h"
+#include "structs.h"
+#include "omalloc.h"
+#include "polys.h"
+#include "febase.h"
+#include "kstd1.h"
+#include "kutil.h"
+#include "stairc.h"
+//#include "cntrlc.h"
+#include "intvec.h"
+#include "numbers.h"
+#include "ideals.h"
+#include "intvec.h"
+#include "ring.h"
+#include "syz.h"
+#include "kbuckets.h"
+#include "prCopy.h"
+
+static kBucket_pt sy0buck;
+
+static void syInitSort(ideal arg,intvec **modcomp)
+{
+  int i,j,k,kk,kkk,jj;
+  polyset F,oldF=arg->m;
+  int Fl=IDELEMS(arg);
+  int rkF=idRankFreeModule(arg);
+  int syComponentOrder=currRing->ComponentOrder;
+
+  while ((Fl!=0) && (oldF[Fl-1]==NULL)) Fl--;
+  if (*modcomp!=NULL) delete modcomp;
+  *modcomp = new intvec(rkF+2);
+  F=(polyset)omAlloc0(IDELEMS(arg)*sizeof(poly));
+  j=0;
+  for(i=0;i<=rkF;i++)
+  {
+    k=0;
+    jj = j;
+    (**modcomp)[i] = j;
+    while (k<Fl)
+    {
+      while ((k<Fl) && (pGetComp(oldF[k]) != i)) k++;
+      if (k<Fl)
+      {
+        kk=jj;
+        while ((kk<Fl) && (F[kk]) && (pLmCmp(oldF[k],F[kk])!=syComponentOrder))
+        {
+            kk++;
+        }
+        for (kkk=j;kkk>kk;kkk--)
+        {
+          F[kkk] = F[kkk-1];
+        }
+        F[kk] = oldF[k];
+//Print("Element %d: ",kk);pWrite(F[kk]);
+        j++;
+        k++;
+      }
+    }
+  }
+  (**modcomp)[rkF+1] = Fl;
+  arg->m = F;
+  omFreeSize((ADDRESS)oldF,IDELEMS(arg)*sizeof(poly));
+#ifndef __OPTIMIZE__
+//Print("Neue Anordnung: ");
+//idPrint(arg);
+#endif
+}
+
+static void syCreatePairs(polyset F,int lini,int wend,int k,int j,int i,
+           polyset pairs,int regularPairs=0,ideal mW=NULL)
+{
+  int l,ii=0,jj;
+  poly p,q;
+
+  while (((k<wend) && (pGetComp(F[k]) == i)) ||
+         ((currQuotient!=NULL) && (k<regularPairs+IDELEMS(currQuotient))))
+  {
+    p = pOne();
+    if ((k<wend) && (pGetComp(F[k]) == i) && (k!=j))
+      pLcm(F[j],F[k],p);
+    else if (ii<IDELEMS(currQuotient))
+    {
+      q = pHead(F[j]);
+      if (mW!=NULL)
+      {
+        for(jj=1;jj<=pVariables;jj++)
+          pSetExp(q,jj,pGetExp(q,jj) -pGetExp(mW->m[pGetComp(q)-1],jj));
+        pSetm(q);
+      }
+      pLcm(q,currQuotient->m[ii],p);
+      if (mW!=NULL)
+      {
+        for(jj=1;jj<=pVariables;jj++)
+          pSetExp(p,jj,pGetExp(p,jj) +pGetExp(mW->m[pGetComp(p)-1],jj));
+        pSetm(p);
+      }
+      pDelete(&q);
+      k = regularPairs+ii;
+      ii++;
+    }
+    l=lini;
+    while ((l<k) && ((pairs[l]==NULL) || (!pDivisibleBy(pairs[l],p))))
+    {
+      if ((pairs[l]!=NULL) && (pDivisibleBy(p,pairs[l])))
+        pDelete(&(pairs[l]));
+      l++;
+    }
+    if (l==k)
+    {
+      pSetm(p);
+      pairs[l] = p;
+    }
+    else
+      pDelete(&p);
+    k++;
+  }
+}
+
+static poly syRedtail2(poly p, polyset redWith, intvec *modcomp)
+{
+  poly h, hn;
+  int hncomp,nxt;
+  int j;
+
+  h = p;
+  hn = pNext(h);
+  while(hn != NULL)
+  {
+    hncomp = pGetComp(hn);
+    j = (*modcomp)[hncomp];
+    nxt = (*modcomp)[hncomp+1];
+    while (j < nxt)
+    {
+      if (pLmDivisibleByNoComp(redWith[j], hn))
+      {
+        //if (TEST_OPT_PROT) Print("r");
+        hn = ksOldSpolyRed(redWith[j],hn);
+        if (hn == NULL)
+        {
+          pNext(h) = NULL;
+          return p;
+        }
+        hncomp = pGetComp(hn);
+        j = (*modcomp)[hncomp];
+        nxt = (*modcomp)[hncomp+1];
+      }
+      else
+      {
+        j++;
+      }
+    }
+    h = pNext(h) = hn;
+    hn = pNext(h);
+  }
+  return p;
+}
+
+/*2
+* computes the Schreyer syzygies in the local case
+* input: arg   (only allocated: Shdl, Smax)
+* output: Shdl, Smax
+*/
+static ideal sySchreyersSyzygiesFM(ideal arg,intvec ** modcomp)
+{
+  int Fl=IDELEMS(arg);
+  while ((Fl!=0) && (arg->m[Fl-1]==NULL)) Fl--;
+  ideal result=idInit(16,arg->rank+Fl);
+  polyset F=arg->m,*Shdl=&(result->m);
+  if (Fl==0) return result;
+
+  int i,j,l,k,totalToRed,ecartToRed,kk,kkk;
+  int bestEcart,totalmax,rkF,Sl=0,smax,tmax,tl;
+  int *ecartS, *ecartT, *totalS,
+    *totalT=NULL, *temp=NULL;
+  polyset pairs,S,T,ST,oldF;
+  poly p,q,toRed;
+  BOOLEAN notFound = FALSE;
+  intvec * newmodcomp = new intvec(Fl+2);
+  intvec * tempcomp;
+
+//Print("Naechster Modul\n");
+//idPrint(arg);
+/*-------------initializing the sets--------------------*/
+  ST=(polyset)omAlloc0(Fl*sizeof(poly));
+  S=(polyset)omAlloc0(Fl*sizeof(poly));
+  ecartS=(int*)omAlloc(Fl*sizeof(int));
+  totalS=(int*)omAlloc(Fl*sizeof(int));
+  T=(polyset)omAlloc0(2*Fl*sizeof(poly));
+  ecartT=(int*)omAlloc(2*Fl*sizeof(int));
+  totalT=(int*)omAlloc(2*Fl*sizeof(int));
+  pairs=(polyset)omAlloc0(Fl*sizeof(poly));
+
+  smax = Fl;
+  tmax = 2*Fl;
+  for (j=1;j<IDELEMS(arg);j++)
+  {
+    if (arg->m[j] != NULL)
+    {
+      assume (arg->m[j-1] != NULL);
+      assume (pGetComp(arg->m[j-1])-pGetComp(arg->m[j])<=0);
+    }
+  }
+  rkF=idRankFreeModule(arg);
+/*----------------construction of the new ordering----------*/
+  if (rkF>0)
+    rSetSyzComp(rkF);
+  else 
+    rSetSyzComp(1);
+/*----------------creating S--------------------------------*/
+  for(j=0;j<Fl;j++)
+  {
+    S[j] = pCopy(F[j]);
+    totalS[j] = pLDeg(S[j],&k);
+    ecartS[j] = totalS[j]-pFDeg(S[j]);
+//Print("%d", pGetComp(S[j]));PrintS("  ");
+    p = S[j];
+    if (rkF==0) pSetCompP(p,1);
+    while (pNext(p)!=NULL) pIter(p);
+    pNext(p) = pHead(F[j]);
+    pIter(p);
+    if (rkF==0)
+      pSetComp(p,j+2);
+    else
+      pSetComp(p,rkF+j+1);
+    pSetmComp(p);
+  }
+//PrintLn();
+  if (rkF==0) rkF = 1;
+/*---------------creating the initial for T----------------*/
+  j=0;
+  l=-1;
+  totalmax=-1;
+  for (k=0;k<smax;k++)
+    if (totalS[k]>totalmax) totalmax=totalS[k];
+  for (kk=1;kk<=rkF;kk++)
+  {
+    for (k=0;k<=totalmax;k++)
+    {
+      for (l=0;l<smax;l++)
+      {
+        if ((pGetComp(S[l])==kk) && (totalS[l]==k))
+        {
+          ST[j] = S[l];
+          totalT[j] = totalS[l];
+          ecartT[j] = ecartS[l];
+//Print("%d", totalS[l]);PrintS("  ");
+          j++;
+        }
+      }
+    }
+  }
+//PrintLn();
+  for (j=0;j<smax;j++)
+  {
+     totalS[j] = totalT[j];
+     ecartS[j] = ecartT[j];
+  }
+
+/*---------------computing---------------------------------*/
+  for(j=0;j<smax;j++)
+  {
+    (*newmodcomp)[j+1] = Sl;
+    i = pGetComp(S[j]);
+    int syComponentOrder= currRing->ComponentOrder;
+    int lini,wend;
+    if (syComponentOrder==1)
+    {
+      lini=k=j+1;
+      wend=Fl;
+    }
+    else
+    {
+      lini=k=0;
+      while ((k<j) && (pGetComp(S[k]) != i)) k++;
+      wend=j;
+    }
+    if (TEST_OPT_PROT)
+    {
+      Print("(%d)",Fl-j);
+      mflush();
+    }
+    syCreatePairs(S,lini,wend,k,j,i,pairs);
+    for (k=lini;k<wend;k++)
+    {
+      if (pairs[k]!=NULL)
+      {
+/*--------------creating T----------------------------------*/
+        for (l=0;l<smax;l++)
+        {
+          ecartT[l] = ecartS[l];
+          totalT[l] = totalS[l];
+          T[l] = ST[l];
+        }
+        tl = smax;
+        tempcomp = ivCopy(*modcomp);
+/*--------------begin to reduce-----------------------------*/
+        toRed = ksOldCreateSpoly(S[j],S[k]);
+        ecartToRed = 1;
+        bestEcart = 1;
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("pair: ");pWrite0(S[j]);PrintS(" ");pWrite(S[k]);
+        }
+        if (TEST_OPT_PROT)
+        {
+           PrintS(".");
+           mflush();
+        }
+//Print("Reduziere Paar %d,%d (ecart %d): \n",j,k,ecartToRed);
+//Print("Poly %d: ",j);pWrite(S[j]);
+//Print("Poly %d: ",k);pWrite(S[k]);
+//Print("Spoly: ");pWrite(toRed);
+        while (pGetComp(toRed)<=rkF)
+        {
+          if (TEST_OPT_DEBUG)
+          {
+            PrintS("toRed: ");pWrite(toRed);
+          }
+/*
+*         if ((bestEcart) || (ecartToRed!=0))
+*         {
+*/
+            totalToRed = pLDeg(toRed,&kk);
+            ecartToRed = totalToRed-pFDeg(toRed);
+/*
+*         }
+*/
+//Print("toRed now (neuer ecart %d): ",ecartToRed);pWrite(toRed);
+          notFound = TRUE;
+          bestEcart = 32000;  //a very large integer
+          p = NULL;
+          int l=0;
+#define OLD_SEARCH
+#ifdef OLD_SEARCH
+          while ((l<tl) && (pGetComp(T[l])<pGetComp(toRed))) l++;
+          //assume (l==(**modcomp)[pGetComp(toRed)]);
+          while ((l<tl) && (notFound))
+#else
+          l = (**modcomp)[pGetComp(toRed)];
+          kkk = (**modcomp)[pGetComp(toRed)+1];
+          while ((l<kkk) && (notFound))
+#endif
+          {
+            if ((ecartT[l]<bestEcart) && (pDivisibleBy(T[l],toRed)))
+            {
+              if (ecartT[l]<=ecartToRed) notFound = FALSE;
+              p = T[l];
+              bestEcart = ecartT[l];
+            }
+            l++;
+          }
+          if (p==NULL)
+          {
+            WerrorS("ideal not a standardbasis");//no polynom for reduction
+            pDelete(&toRed);
+            for(k=j;k<Fl;k++) pDelete(&(pairs[k]));
+            omFreeSize((ADDRESS)pairs,Fl*sizeof(poly));
+            omFreeSize((ADDRESS)ST,Fl*sizeof(poly));
+            omFreeSize((ADDRESS)S,Fl*sizeof(poly));
+            omFreeSize((ADDRESS)T,tmax*sizeof(poly));
+            omFreeSize((ADDRESS)ecartT,tmax*sizeof(int));
+            omFreeSize((ADDRESS)totalT,tmax*sizeof(int));
+            omFreeSize((ADDRESS)ecartS,Fl*sizeof(int));
+            omFreeSize((ADDRESS)totalS,Fl*sizeof(int));
+            for(k=0;k<IDELEMS(result);k++) pDelete(&((*Shdl)[k]));
+            return result;
+          }
+          else
+          {
+//Print("reduced with (ecart %d): ",bestEcart);wrp(p);PrintLn();
+            if (notFound)
+            {
+              if (tl>=tmax)
+              {
+                pEnlargeSet(&T,tmax,16);
+                tmax += 16;
+                temp = (int*)omAlloc((tmax+16)*sizeof(int));
+                for(l=0;l<tmax;l++) temp[l]=totalT[l];
+                totalT = temp;
+                temp = (int*)omAlloc((tmax+16)*sizeof(int));
+                for(l=0;l<tmax;l++) temp[l]=ecartT[l];
+                ecartT = temp;
+              }
+//PrintS("t");
+              int comptR=pGetComp(toRed);
+              for (l=tempcomp->length()-1;l>comptR;l--)
+              {
+                if ((*tempcomp)[l]>0)
+                  (*tempcomp)[l]++;
+              }
+              l=0;
+              while ((l<tl) && (comptR>pGetComp(T[l]))) l++;
+              while ((l<tl) && (totalT[l]<=totalToRed)) l++;
+              for (kk=tl;kk>l;kk--)
+              {
+                T[kk]=T[kk-1];
+                totalT[kk]=totalT[kk-1];
+                ecartT[kk]=ecartT[kk-1];
+              }
+              q = pCopy(toRed);
+              pNorm(q);
+              T[l] = q;
+              totalT[l] = totalToRed;
+              ecartT[l] = ecartToRed;
+              tl++;
+            }
+            toRed = ksOldSpolyRed(p,toRed);
+          }
+        }
+//Print("toRed finally (neuer ecart %d): ",ecartToRed);pWrite(toRed);
+//PrintS("s");
+        if (pGetComp(toRed)>rkF)
+        {
+          if (Sl>=IDELEMS(result))
+          {
+            pEnlargeSet(Shdl,IDELEMS(result),16);
+            IDELEMS(result) += 16;
+          }
+          //pShift(&toRed,-rkF);
+          pNorm(toRed);
+          (*Shdl)[Sl] = toRed;
+          Sl++;
+        }
+/*----------------deleting all polys not from ST--------------*/
+        for(l=0;l<tl;l++)
+        {
+          kk=0;
+          while ((kk<smax) && (T[l] != S[kk])) kk++;
+          if (kk>=smax)
+          {
+            pDelete(&T[l]);
+//Print ("#");
+          }
+        }
+        delete tempcomp;
+      }
+    }
+    for(k=lini;k<wend;k++) pDelete(&(pairs[k]));
+  }
+  (*newmodcomp)[Fl+1] = Sl;
+  omFreeSize((ADDRESS)pairs,Fl*sizeof(poly));
+  omFreeSize((ADDRESS)ST,Fl*sizeof(poly));
+  omFreeSize((ADDRESS)S,Fl*sizeof(poly));
+  omFreeSize((ADDRESS)T,tmax*sizeof(poly));
+  omFreeSize((ADDRESS)ecartT,tmax*sizeof(int));
+  omFreeSize((ADDRESS)totalT,tmax*sizeof(int));
+  omFreeSize((ADDRESS)ecartS,Fl*sizeof(int));
+  omFreeSize((ADDRESS)totalS,Fl*sizeof(int));
+  delete *modcomp;
+  *modcomp = newmodcomp;
+  return result;
+}
+
+/*3
+*special Normalform for Schreyer in factor rings
+*/
+poly sySpecNormalize(poly toNorm,ideal mW=NULL)
+{
+  int j,i=0;
+  poly p;
+
+  if (toNorm==NULL) return NULL;
+  p = pHead(toNorm);
+  if (mW!=NULL)
+  {
+    for(j=1;j<=pVariables;j++)
+      pSetExp(p,j,pGetExp(p,j) -pGetExp(mW->m[pGetComp(p)-1],j));
+  }
+  while ((p!=NULL) && (i<IDELEMS(currQuotient)))
+  {
+    if (pDivisibleBy(currQuotient->m[i],p))
+    {
+      //pNorm(toNorm);
+      toNorm = ksOldSpolyRed(currQuotient->m[i],toNorm);
+      pDelete(&p);
+      if (toNorm==NULL) return NULL;
+      p = pHead(toNorm);
+      if (mW!=NULL)
+      {
+        for(j=1;j<=pVariables;j++)
+          pSetExp(p,j,pGetExp(p,j) -pGetExp(mW->m[pGetComp(p)-1],j));
+      }
+      i = 0;
+    }
+    else
+    {
+      i++;
+    }
+  }
+  pDelete(&p);
+  return toNorm;
+}
+
+/*2
+* computes the Schreyer syzygies in the global case
+* input: F
+* output: Shdl, Smax
+* modcomp, length stores the start position of the module comp. in arg
+*/
+static ideal sySchreyersSyzygiesFB(ideal arg,intvec ** modcomp,ideal mW,BOOLEAN redTail=TRUE)
+{
+  int Fl=IDELEMS(arg);
+  while ((Fl!=0) && (arg->m[Fl-1]==NULL)) Fl--;
+  ideal result=idInit(16,Fl);
+  int i,j,l,k,kkk,rkF,Sl=0,syComponentOrder=currRing->ComponentOrder;
+  int fstart,wend,lini,ltR,gencQ=0;
+  intvec *newmodcomp;
+  int *Flength;
+  polyset pairs,F=arg->m,*Shdl=&(result->m);
+  poly p,q,toRed,syz,lastmonom,multWith;
+  BOOLEAN isNotReduced=TRUE;
+
+//#define WRITE_BUCKETS
+#ifdef WRITE_BUCKETS
+PrintS("Input: \n");
+ideal twr=idHead(arg);
+idPrint(arg);
+idDelete(&twr);
+if (modcomp!=NULL) (*modcomp)->show(0,0);
+#endif
+  newmodcomp = new intvec(Fl+2);
+//for (j=0;j<Fl;j++) pWrite(F[j]);
+//PrintLn();
+  if (currQuotient==NULL)
+    pairs=(polyset)omAlloc0(Fl*sizeof(poly));
+  else
+  {
+    gencQ = IDELEMS(currQuotient);
+    pairs=(polyset)omAlloc0((Fl+gencQ)*sizeof(poly));
+  }
+  rkF=idRankFreeModule(arg);
+  Flength = (int*)omAlloc0(Fl*sizeof(int));
+  for(j=0;j<Fl;j++)
+  {
+    Flength[j] = pLength(F[j]);
+  }
+  for(j=0;j<Fl;j++)
+  {
+    (*newmodcomp)[j+1] = Sl;
+    if (TEST_OPT_PROT)
+    {
+      Print("(%d)",Fl-j);
+      mflush();
+    }
+    i = pGetComp(F[j]);
+    if (syComponentOrder==1)
+    {
+      lini=k=j+1;
+      wend=Fl;
+    }
+    else
+    {
+      lini=k=0;
+      while ((k<j) && (pGetComp(F[k]) != i)) k++;
+      wend=j;
+    }
+    syCreatePairs(F,lini,wend,k,j,i,pairs,Fl,mW);
+    if (currQuotient!=NULL) wend = Fl+gencQ;
+    for (k=lini;k<wend;k++)
+    {
+      if (pairs[k]!=NULL)
+      {
+        if (TEST_OPT_PROT)
+        {
+           PrintS(".");
+           mflush();
+        }
+        //begins to construct the syzygy
+        if (k<Fl)
+        {
+          number an=nCopy(pGetCoeff(F[k])),bn=nCopy(pGetCoeff(F[j]));
+          int ct = ksCheckCoeff(&an, &bn);
+          syz = pCopy(pairs[k]);
+          //syz->coef = nCopy(F[k]->coef);
+          syz->coef = an;
+          //syz->coef = nNeg(syz->coef);
+          pNext(syz) = pairs[k];
+          lastmonom = pNext(syz);
+          //lastmonom->coef = nCopy(F[j]->coef);
+          lastmonom->coef = bn;
+          lastmonom->coef = nNeg(lastmonom->coef);
+          pSetComp(lastmonom,k+1);
+        }
+        else
+        {
+          syz = pairs[k];
+          syz->coef = nCopy(currQuotient->m[k-Fl]->coef);
+          syz->coef = nNeg(syz->coef);
+          lastmonom = syz;
+          multWith = pDivide(syz,F[j]);
+          multWith->coef = nCopy(currQuotient->m[k-Fl]->coef);
+        }
+        pSetComp(syz,j+1);
+        pairs[k] = NULL;
+        //the next term of the syzygy
+        //constructs the spoly
+        if (TEST_OPT_DEBUG)
+        {
+          if (k<Fl)
+          {
+            PrintS("pair: ");pWrite0(F[j]);PrintS("  ");pWrite(F[k]);
+          }
+          else
+          {
+            PrintS("pair: ");pWrite0(F[j]);PrintS("  ");pWrite(currQuotient->m[k-Fl]);
+          }
+        }
+        if (k<Fl)
+          toRed = ksOldCreateSpoly(F[j],F[k]);
+        else
+        {
+          q = pMult_mm(pCopy(F[j]),multWith);
+          toRed = sySpecNormalize(q,mW);
+          pDelete(&multWith);
+        }
+        kBucketInit(sy0buck,toRed,-1);
+        toRed = kBucketGetLm(sy0buck);
+        isNotReduced = TRUE;
+        while (toRed!=NULL)
+        {
+          if (TEST_OPT_DEBUG)
+          {
+            PrintS("toRed: ");pWrite(toRed);
+          }
+//          l=0;
+//          while ((l<Fl) && (!pDivisibleBy(F[l],toRed))) l++;
+//          if (l>=Fl)
+          l = (**modcomp)[pGetComp(toRed)+1]-1;
+          kkk = (**modcomp)[pGetComp(toRed)];
+          while ((l>=kkk) && (!pDivisibleBy(F[l],toRed))) l--;
+#ifdef WRITE_BUCKETS
+          kBucketClear(sy0buck,&toRed,&ltR);
+          printf("toRed in Pair[%d, %d]:", j, k);
+          pWrite(toRed);
+          kBucketInit(sy0buck,toRed,-1);
+#endif
+
+          if (l<kkk)
+          {
+            if ((currQuotient!=NULL) && (isNotReduced))
+            {
+              kBucketClear(sy0buck,&toRed,&ltR);
+              toRed = sySpecNormalize(toRed,mW);
+#ifdef WRITE_BUCKETS
+              printf("toRed in Pair[%d, %d]:", j, k);
+              pWrite(toRed);
+#endif
+              kBucketInit(sy0buck,toRed,-1);
+              toRed = kBucketGetLm(sy0buck);
+              isNotReduced = FALSE;
+            }
+            else
+            {
+              //no polynom for reduction
+              WerrorS("ideal not a standardbasis");
+              pDelete(&toRed);
+              pDelete(&syz);
+              for(k=j;k<Fl;k++) pDelete(&(pairs[k]));
+              omFreeSize((ADDRESS)pairs,(Fl + gencQ)*sizeof(poly));
+              for(k=0;k<IDELEMS(result);k++) pDelete(&((*Shdl)[k]));
+              return result;
+            }
+          }
+          else
+          {
+            //the next monom of the syzygy
+            isNotReduced = TRUE;
+            if (TEST_OPT_DEBUG)
+            {
+              PrintS("reduced with: ");pWrite(F[l]);
+            }
+            pNext(lastmonom) = pHead(toRed);
+            pIter(lastmonom);
+            lastmonom->coef = nDiv(lastmonom->coef,F[l]->coef);
+            //lastmonom->coef = nNeg(lastmonom->coef);
+            pSetComp(lastmonom,l+1);
+            //computes the new toRed
+            number up = kBucketPolyRed(sy0buck,F[l],Flength[l],NULL);
+            if (! nIsOne(up))
+            {
+              // Thomas: Now do whatever you need to do
+#ifdef WRITE_BUCKETS
+              PrintS("multiplied with: ");nWrite(up);PrintLn();
+#endif
+              pMult_nn(syz,up);
+            }
+            nDelete(&up);
+
+            toRed = kBucketGetLm(sy0buck);
+            //the module component of the new monom
+//pWrite(toRed);
+          }
+        }
+        kBucketClear(sy0buck,&toRed,&ltR); //Zur Sichereheit
+//PrintLn();
+        if (syz!=NULL)
+        {
+          if (Sl>=IDELEMS(result))
+          {
+            pEnlargeSet(Shdl,IDELEMS(result),16);
+            IDELEMS(result) += 16;
+          }
+          pNorm(syz);
+          if (BTEST1(OPT_REDTAIL) && redTail)
+          {
+            (*newmodcomp)[j+2] = Sl;
+            (*Shdl)[Sl] = syRedtail2(syz,*Shdl,newmodcomp);
+            (*newmodcomp)[j+2] = 0;
+          }
+          else
+            (*Shdl)[Sl] = syz;
+          Sl++;
+        }
+      }
+    }
+//    for(k=j;k<Fl;k++) pDelete(&(pairs[k]));
+  }
+  (*newmodcomp)[Fl+1] = Sl;
+  if (currQuotient==NULL)
+    omFreeSize((ADDRESS)pairs,Fl*sizeof(poly));
+  else
+    omFreeSize((ADDRESS)pairs,(Fl+IDELEMS(currQuotient))*sizeof(poly));
+  omFreeSize((ADDRESS)Flength,Fl*sizeof(int));
+  delete *modcomp;
+  *modcomp = newmodcomp;
+  return result;
+}
+
+void syReOrderResolventFB(resolvente res,int length, int initial)
+{
+  int syzIndex=length-1,i,j;
+  poly p;
+
+  while ((syzIndex!=0) && (res[syzIndex]==NULL)) syzIndex--;
+  while (syzIndex>=initial)
+  {
+    for(i=0;i<IDELEMS(res[syzIndex]);i++)
+    {
+      p = res[syzIndex]->m[i];
+
+      while (p!=NULL)
+      {
+        if (res[syzIndex-1]->m[pGetComp(p)-1]!=NULL)
+        {
+          for(j=1;j<=pVariables;j++)
+          {
+            pSetExp(p,j,pGetExp(p,j)
+                        -pGetExp(res[syzIndex-1]->m[pGetComp(p)-1],j));
+          }
+        }
+        else
+          PrintS("error in the resolvent\n");
+        pSetm(p);
+        pIter(p);
+      }
+    }
+    syzIndex--;
+  }
+}
+
+static void syMergeSortResolventFB(resolvente res,int length, int initial=1)
+{
+  int syzIndex=length-1,i,j;
+  poly qq,pp,result=NULL;
+  poly p;
+
+  while ((syzIndex!=0) && (res[syzIndex]==NULL)) syzIndex--;
+  while (syzIndex>=initial)
+  {
+    for(i=0;i<IDELEMS(res[syzIndex]);i++)
+    {
+      p = res[syzIndex]->m[i];
+      if (p != NULL)
+      {
+        for (;;)
+        {
+          qq = p;
+          for(j=1;j<=pVariables;j++)
+          {
+            pSetExp(p,j,pGetExp(p,j)
+                        -pGetExp(res[syzIndex-1]->m[pGetComp(p)-1],j));
+          }
+          pSetm(p);
+          for (;;)
+          {
+            if (pNext(p) == NULL)
+            {
+              pAdd(result, qq);
+              break;
+            }
+            pp = pNext(p);
+            for(j=1;j<=pVariables;j++)
+            {
+              pSetExp(pp,j,pGetExp(pp,j)
+                          -pGetExp(res[syzIndex-1]->m[pGetComp(pp)-1],j));
+            }
+            pSetm(pp);
+            if (pCmp(p,pNext(p)) != 1)
+            {
+              pp = p;
+              pIter(p);
+              pNext(pp) = NULL;
+              result = pAdd(result, qq);
+              break;
+            }
+            pIter(p);
+          }
+        }
+      }
+      res[syzIndex]->m[i] = p;
+    }
+    syzIndex--;
+  }
+}
+
+BOOLEAN syTestOrder(ideal M)
+{
+  int i=idRankFreeModule(M);
+  if (i == 0) return FALSE;
+  int j=0;
+
+  while ((currRing->order[j]!=ringorder_c) && (currRing->order[j]!=ringorder_C))
+    j++;
+  if (currRing->order[j+1]!=0)
+    return TRUE;
+  return FALSE;
+}
+
+static void idShift(ideal arg,int index)
+{
+  int i,j=rGetMaxSyzComp(index);
+  for (i=0;i<IDELEMS(arg);i++)
+  {
+    if (arg->m[i]!=NULL)
+      pShift(&arg->m[i],-j);
+  }
+}
+
+static void syPrintResolution(resolvente res,int start,int length)
+{
+  while ((start < length) && (res[start]))
+  {
+    Print("Syz(%d): \n",start);
+    idTest(res[start]);
+    //idPrint(res[start]);
+    start++;
+  }  
+}
+
+resolvente sySchreyerResolvente(ideal arg, int maxlength, int * length,
+                                BOOLEAN isMonomial, BOOLEAN notReplace)
+{
+  ideal mW=NULL;
+  int i,syzIndex = 0,j=0;
+  intvec * modcomp=NULL,*w=NULL;
+  int ** wv=NULL;
+  tHomog hom=(tHomog)idHomModule(arg,NULL,&w);
+  ring origR = currRing;
+  ring syRing=NULL;
+
+  if ((!isMonomial) && syTestOrder(arg))
+  {
+    WerrorS("sres only implemented for modules with ordering  ..,c or ..,C");
+    return NULL;
+  }
+  *length = 4;
+  resolvente res = (resolvente)omAlloc0(4*sizeof(ideal)),newres;
+  res[0] = idCopy(arg);
+  while ((!idIs0(res[syzIndex])) && ((maxlength==-1) || (syzIndex<maxlength)))
+  {
+    i = IDELEMS(res[syzIndex]);
+    //while ((i!=0) && (!res[syzIndex]->m[i-1])) i--;
+    sy0buck = kBucketCreate();
+    if (syzIndex+1==*length)
+    {
+      newres = (resolvente)omAlloc((*length+4)*sizeof(ideal));
+      for (j=0;j<*length+4;j++) newres[j] = NULL;
+      for (j=0;j<*length;j++) newres[j] = res[j];
+      omFreeSize((ADDRESS)res,*length*sizeof(ideal));
+      *length += 4;
+      res=newres;
+    }
+    if ((hom==isHomog)|| (origR->OrdSgn == 1))
+    {
+      if (syzIndex==0) syInitSort(res[0],&modcomp);
+      if ((syzIndex==0) && !rRing_has_CompLastBlock(currRing))
+        res[syzIndex+1] = sySchreyersSyzygiesFB(res[syzIndex],&modcomp,mW,FALSE);
+      else
+        res[syzIndex+1] = sySchreyersSyzygiesFB(res[syzIndex],&modcomp,mW);
+      mW = res[syzIndex];
+    }
+//idPrint(res[syzIndex+1]);
+
+    if ((syzIndex==0))
+    {
+      if ((hom==isHomog)|| (origR->OrdSgn == 1))
+      {
+        syRing = rCurrRingAssure_CompLastBlock();
+        if (syRing != origR)
+        {
+          for (i=0; i<IDELEMS(res[1]); i++)
+          {
+            res[1]->m[i] = prMoveR( res[1]->m[i], origR);
+          }
+        }
+        idTest(res[1]);
+      }
+      else
+      {
+        syRing = rCurrRingAssure_SyzComp_CompLastBlock();
+        if (syRing != origR)
+        {
+          for (i=0; i<IDELEMS(res[0]); i++)
+          {
+            res[0]->m[i] = prMoveR( res[0]->m[i], origR);
+          }
+        }
+        idTest(res[0]);
+      }
+    }
+    if ((hom!=isHomog) && (origR->OrdSgn != 1))
+    {
+      if (syzIndex==0) syInitSort(res[0],&modcomp);
+      res[syzIndex+1] = sySchreyersSyzygiesFM(res[syzIndex],&modcomp);
+    }
+    syzIndex++;
+    if (TEST_OPT_PROT) Print("[%d]\n",syzIndex);
+    kBucketDestroy(&(sy0buck));
+  }
+  //syPrintResolution(res,1,*length);
+  if ((hom!=isHomog) && (origR->OrdSgn != 1))
+  {
+    syzIndex = 1;
+    while ((syzIndex < *length) && (!idIs0(res[syzIndex])))
+    {
+      idShift(res[syzIndex],syzIndex);
+      syzIndex++;
+    }
+  }
+  if ((hom==isHomog) || (origR->OrdSgn == 1))
+    syzIndex = 1;
+  else
+    syzIndex = 0;
+  syReOrderResolventFB(res,*length,syzIndex+1);
+  if (/*ringOrderChanged:*/ origR!=syRing && syRing != NULL)
+  {
+    rChangeCurrRing(origR);
+    // Thomas: Here I assume that all (!) polys of res live in tmpR
+    while ((syzIndex < *length) && (res[syzIndex]))
+    {
+      for (i=0;i<IDELEMS(res[syzIndex]);i++)
+      {
+        if (res[syzIndex]->m[i])
+        {
+          res[syzIndex]->m[i] = prMoveR( res[syzIndex]->m[i], syRing);
+        }
+      }
+      syzIndex++;
+    }
+    j = 0;
+    while (currRing->order[j]!=0) j++;
+    rKill(syRing);
+  }
+  else
+  {
+    // Thomas -- are you sure that you have to "reorder" here?
+    while ((syzIndex < *length) && (res[syzIndex]))
+    {
+      for (i=0;i<IDELEMS(res[syzIndex]);i++)
+      {
+        if (res[syzIndex]->m[i])
+          res[syzIndex]->m[i] = pSortCompCorrect(res[syzIndex]->m[i]);
+      }
+      syzIndex++;
+    }
+  }
+  if ((hom==isHomog) || (origR->OrdSgn == 1))
+  {
+    if (res[1]!=NULL)
+    {
+      syReOrderResolventFB(res,2,1);
+      for (i=0;i<IDELEMS(res[1]);i++)
+      {
+        if (res[1]->m[i])
+          res[1]->m[i] = pSort(res[1]->m[i]);
+      }
+    }
+  }
+  //syPrintResolution(res,0,*length);
+
+  //syMergeSortResolventFB(res,*length);
+  if (modcomp!=NULL) delete modcomp;
+  if (w!=NULL) delete w;
+  return res;
+}
+
+syStrategy sySchreyer(ideal arg, int maxlength)
+{
+  int rl;
+  resolvente fr = sySchreyerResolvente(arg,maxlength,&(rl));
+  if (fr==NULL) return NULL;
+
+  int typ0;
+  syStrategy result=(syStrategy)omAlloc0(sizeof(ssyStrategy));
+  result->length=rl;
+  result->fullres = (resolvente)omAlloc0((rl /*result->length*/+1)*sizeof(ideal));
+  for (int i=rl /*result->length*/-1;i>=0;i--)
+  {
+    if (fr[i]!=NULL)
+      result->fullres[i] = fr[i];
+      fr[i] = NULL;
+  }
+  omFreeSize((ADDRESS)fr,(rl /*result->length*/)*sizeof(ideal));
+  return result;
+}
+
Index: kernel/syz1.cc
===================================================================
--- kernel/syz1.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/syz1.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,2635 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: syz1.cc,v 1.1.1.1 2003-10-06 12:15:55 Singular Exp $ */
+/*
+* ABSTRACT: resolutions
+*/
+
+#include "mod2.h"
+#include <mylimits.h>
+#include "structs.h"
+#include "omalloc.h"
+#include "polys.h"
+#include "febase.h"
+#include "kstd1.h"
+#include "kutil.h"
+#include "stairc.h"
+#include "cntrlc.h"
+#include "intvec.h"
+#include "numbers.h"
+#include "modulop.h"
+#include "ideals.h"
+#include "intvec.h"
+#include "ring.h"
+#include "syz.h"
+#include "kbuckets.h"
+#include "prCopy.h"
+
+extern void p_Setm_Syz(poly p, ring r,
+                       int* Components, long* ShiftedComponents);
+
+/*--------------static variables------------------------*/
+/*---points to the real components, shifted of the actual module-*/
+int *  currcomponents=NULL;
+long *  currShiftedComponents=NULL;
+
+
+/*---head-term-polynomials for the reduction------------*/
+static poly redpol=NULL;
+/*---counts number of applications of GM-criteria-------*/
+//static int crit;
+//static int euler;
+
+/*3
+* deletes all entres of a pair
+*/
+void syDeletePair(SObject * so)
+{
+  pDelete(&(*so).p);
+  pDelete(&(*so).lcm);
+  pDelete(&(*so).syz);
+  (*so).p1 = NULL;
+  (*so).p2 = NULL;
+  (*so).ind1 = 0;
+  (*so).ind2 = 0;
+  (*so).syzind = -1;
+  (*so).order = 0;
+  (*so).isNotMinimal = NULL;
+  (*so).length = -1;
+  (*so).reference = -1;
+}
+
+/*3
+* initializes all entres of a pair
+*/
+void syInitializePair(SObject * so)
+{
+  (*so).p = NULL;
+  (*so).lcm = NULL;
+  (*so).syz = NULL;
+  (*so).p1 = NULL;
+  (*so).p2 = NULL;
+  (*so).ind1 = 0;
+  (*so).ind2 = 0;
+  (*so).syzind = -1;
+  (*so).order = 0;
+  (*so).isNotMinimal = NULL;
+  (*so).length = -1;
+  (*so).reference = -1;
+}
+
+/*3
+* puts all entres of a pair to another
+*/
+void syCopyPair(SObject * argso, SObject * imso)
+{
+  *imso=*argso;
+  (*argso).p = NULL;
+  (*argso).p1 = NULL;
+  (*argso).p2 = NULL;
+  (*argso).lcm = NULL;
+  (*argso).syz = NULL;
+  (*argso).ind1 = 0;
+  (*argso).ind2 = 0;
+  (*argso).syzind = -1;
+  (*argso).order = 0;
+  (*argso).isNotMinimal = NULL;
+  (*argso).length = -1;
+  (*argso).reference = -1;
+}
+
+/*3
+* deletes empty objects from a pair set beginning with
+* pair first
+* assumes a pair to be empty if .lcm does so
+*/
+void syCompactifyPairSet(SSet sPairs, int sPlength, int first)
+{
+  int k=first,kk=0;
+
+  while (k+kk<sPlength)
+  {
+    if (sPairs[k+kk].lcm!=NULL)
+    {
+      if (kk>0) syCopyPair(&sPairs[k+kk],&sPairs[k]);
+      k++;
+    }
+    else
+    {
+      kk++;
+    }
+  }
+  while (k<sPlength)
+  {
+    syInitializePair(&sPairs[k]);
+    k++;
+  }
+}
+
+/*3
+* deletes empty objects from a pair set beginning with
+* pair first
+* assumes a pair to be empty if .lcm does so
+*/
+void syCompactify1(SSet sPairs, int* sPlength, int first)
+{
+  int k=first,kk=0;
+
+  while (k+kk<*sPlength)
+  {
+    if (sPairs[k+kk].lcm!=NULL)
+    {
+      if (kk>0) syCopyPair(&sPairs[k+kk],&sPairs[k]);
+      k++;
+    }
+    else
+    {
+      kk++;
+    }
+  }
+  while (k<*sPlength)
+  {
+    syInitializePair(&sPairs[k]);
+    k++;
+  }
+  *sPlength -= kk;
+}
+
+/*3
+* replaces comp1dpc during homogeneous syzygy-computations
+* compares with components of currcomponents instead of the
+* exp[0]
+*/
+static int syzcomp0dpc(poly p1, poly p2)
+{
+  /*4 compare monomials by order then revlex*/
+    int i = pVariables;
+    if ((pGetExp(p1,i) == pGetExp(p2,i)))
+    {
+      do
+      {
+        i--;
+        if (i <= 1)
+        {
+           /*4 handle module case:*/
+           if (pGetComp(p1)==pGetComp(p2)) return 0;
+           else if
+              (currcomponents[pGetComp(p1)]>currcomponents[pGetComp(p2)])
+                return 1;
+           else return -1;
+        }
+      } while ((pGetExp(p1,i) == pGetExp(p2,i)));
+    }
+    if (pGetExp(p1,i) < pGetExp(p2,i)) return 1;
+    return -1;
+}
+
+/*3
+* replaces comp1dpc during homogeneous syzygy-computations
+* compares with components of currcomponents instead of the
+* exp[0]
+*/
+int syzcomp1dpc(poly p1, poly p2)
+{
+  int i = pVariables;
+  while ((i>1) && (pGetExp(p1,i)==pGetExp(p2,i)))
+    i--;
+  if (i>1)
+  {
+    if (pGetExp(p1,i) < pGetExp(p2,i)) return 1;
+    return -1;
+  }
+  int o1=pGetComp(p1);
+  int o2=pGetComp(p2);
+  if (o1==o2/*pGetComp(p1)==pGetComp(p2)*/) return 0;
+  if (currcomponents[o1]>currcomponents[o2]) return 1;
+  return -1;
+
+}
+
+/*3
+* replaces comp1dpc during homogeneous syzygy-computations
+* compares with components of currcomponents instead of the
+* exp[0]
+*/
+
+#ifdef PDEBUG
+static int syzcomp2dpc_test(poly p1, poly p2)
+{
+  long c1, c2, cc1, cc2, ccc1, ccc2, ec1, ec2;
+  c1 = pGetComp(p1);
+  c2 = pGetComp(p2);
+  cc1 = currcomponents[c1];
+  cc2 = currcomponents[c2];
+  ccc1 = currShiftedComponents[cc1];
+  ccc2 = currShiftedComponents[cc2];
+  ec1 = p1->exp[currRing->typ[1].data.syzcomp.place];
+  ec2 = p2->exp[currRing->typ[1].data.syzcomp.place];
+
+  if (ec1 != ccc1)
+  {
+    Warn("Shifted comp of p1 out of sync. should %d, is %d", ccc1, ec1);
+    //mmDBInfoBlock(p1);
+  }
+  if (ec2 != ccc2)
+  {
+    Warn("Shifted comp of p2 out of sync. should %d, is %d", ccc2, ec2);
+    //mmDBInfoBlock(p2);
+  }
+
+  if (c1 == c2)
+  {
+    assume(ccc1 == ccc2);
+  }
+  else if (cc1 > cc2)
+  {
+    assume(ccc1 > ccc2);
+  }
+  else
+  {
+    assume (cc1 < cc2);
+    assume (ccc1 < ccc2);
+  }
+  int o1=pGetOrder(p1), o2=pGetOrder(p2);
+  if (o1 > o2) return 1;
+  if (o1 < o2) return -1;
+
+  //if (o1>0)
+  {
+    int i = pVariables;
+    while ((i>1) && (pGetExp(p1,i)==pGetExp(p2,i)))
+      i--;
+    //(*orderingdepth)[pVariables-i]++;
+    if (i>1)
+    {
+      if (pGetExp(p1,i) < pGetExp(p2,i)) return 1;
+      return -1;
+    }
+  }
+  o1=pGetComp(p1);
+  o2=pGetComp(p2);
+  if (o1==o2/*pGetComp(p1)==pGetComp(p2)*/) return 0;
+  if (currcomponents[o1]>currcomponents[o2]) return 1;
+  return -1;
+}
+#endif // PDEBUG
+
+/*3
+* compares only the monomial without component
+*/
+static int syzcompmonomdp(poly p1, poly p2)
+{
+  int i;
+
+  /*4 compare monomials by order then revlex*/
+  if (pGetOrder(p1) == pGetOrder(p2))
+  {
+    i = pVariables;
+    if ((pGetExp(p1,i) == pGetExp(p2,i)))
+    {
+      do
+      {
+        i--;
+        if (i <= 1)
+          return 0;
+      } while ((pGetExp(p1,i) == pGetExp(p2,i)));
+    }
+    if (pGetExp(p1,i) < pGetExp(p2,i)) return 1;
+    return -1;
+  }
+  else if (pGetOrder(p1) > pGetOrder(p2)) return 1;
+  return -1;
+}
+
+static int syLength(poly p)
+{
+  int result=0;
+
+  while (p!=NULL)
+  {
+    result++;
+    pIter(p);
+  }
+  return result;
+}
+
+poly syRedtail (poly p, syStrategy syzstr, int index)
+{
+  poly h, hn;
+  int j,pos;
+  ideal redWith=syzstr->orderedRes[index];
+
+  h = p;
+  hn = pNext(h);
+  while(hn != NULL)
+  {
+    j = syzstr->Firstelem[index-1][pGetComp(hn)]-1;
+    if (j>=0)
+    {
+      pos = j+syzstr->Howmuch[index-1][pGetComp(hn)];
+      while (j < pos)
+      {
+        if (pLmDivisibleByNoComp(redWith->m[j], hn))
+        {
+          //hn = sySPolyRed(hn,redWith->m[j]);
+          hn = ksOldSpolyRed(redWith->m[j],hn);
+          if (hn == NULL)
+          {
+            pNext(h) = NULL;
+            return p;
+          }
+          j = syzstr->Firstelem[index-1][pGetComp(hn)]-1;
+          pos = j+syzstr->Howmuch[index-1][pGetComp(hn)];
+        }
+        else
+        {
+          j++;
+        }
+      }
+    }
+    h = pNext(h) = hn;
+    hn = pNext(h);
+  }
+  return p;
+}
+
+
+/*3
+* local procedure for of syInitRes for the module case
+*/
+static int syChMin(intvec * iv)
+{
+  int i,j=-1,r=-1;
+
+  for (i=iv->length()-1;i>=0;i--)
+  {
+    if ((*iv)[i]>=0)
+    {
+      if ((j<0) || ((*iv)[i]<j))
+      {
+        j = (*iv)[i];
+        r = i;
+      }
+    }
+  }
+  return r;
+}
+
+/*3
+* initialize the resolution and puts in the argument as
+* zeroth entre, length must be > 0
+* assumes that the basering is degree-compatible
+*/
+SRes syInitRes(ideal arg,int * length, intvec * Tl, intvec * cw)
+{
+  if (idIs0(arg)) return NULL;
+  SRes resPairs = (SRes)omAlloc0(*length*sizeof(SSet));
+  resPairs[0] = (SSet)omAlloc0(IDELEMS(arg)*sizeof(SObject));
+  intvec * iv=NULL;
+  int i,j;
+
+  if (idRankFreeModule(arg)==0)
+  {
+    iv = idSort(arg);
+    for (i=0;i<IDELEMS(arg);i++)
+    {
+      (resPairs[0])[i].syz = /*pCopy*/(arg->m[(*iv)[i]-1]);
+      arg->m[(*iv)[i]-1] = NULL;
+      (resPairs[0])[i].order = pTotaldegree((resPairs[0])[i].syz);
+    }
+  }
+  else
+  {
+    iv = new intvec(IDELEMS(arg),1,-1);
+    for (i=0;i<IDELEMS(arg);i++)
+    {
+      (*iv)[i] = pTotaldegree(arg->m[i])+(*cw)[pGetComp(arg->m[i])-1];
+    }
+    for (i=0;i<IDELEMS(arg);i++)
+    {
+      j = syChMin(iv);
+      if (j<0) break;
+      (resPairs[0])[i].syz = arg->m[j];
+      arg->m[j] = NULL;
+      (resPairs[0])[i].order = (*iv)[j];
+      (*iv)[j] = -1;
+    }
+  }
+  if (iv!=NULL)  delete iv;
+  (*Tl)[0] = IDELEMS(arg);
+  return resPairs;
+}
+
+// rearrange shifted components
+long syReorderShiftedComponents(long * sc, int n)
+{
+  long holes = 0;
+  int i;
+  long new_comps = 0, new_space, max;
+
+  // count number of holes
+  for (i=1; i<n; i++)
+  {
+    if (sc[i-1] + 1 < sc[i]) holes++;
+  }
+
+  if (LONG_MAX - SYZ_SHIFT_BASE <= sc[n-1])
+  {
+    // need new components
+    new_comps = (((long) 1) << SYZ_SHIFT_MAX_NEW_COMP_ESTIMATE) - 1;
+    max = LONG_MAX;
+  }
+  else
+  {
+    max = sc[n-1] + SYZ_SHIFT_BASE;
+  }
+
+  // no we arrange things such that
+  // (n - holes) + holes*new_space + new_comps*SYZ_SHIFT_BASE= LONG_MAX
+  new_space = (max - n + holes - new_comps*SYZ_SHIFT_BASE) / holes;
+
+  assume(new_space < SYZ_SHIFT_BASE && new_space >= 4);
+
+  long* tc = ( long*) omAlloc(n*sizeof(long));
+  tc[0] = sc[0];
+  // rearrange things
+  for (i=1; i<n; i++)
+  {
+    if (sc[i-1] + 1 < sc[i])
+    {
+      tc[i] = tc[i-1] + new_space;
+    }
+    else
+    {
+      tc[i] = tc[i-1] + 1;
+    }
+    assume(tc[i] > tc[i-1]);
+  }
+
+  assume(LONG_MAX -  SYZ_SHIFT_BASE > tc[n-1]);
+#ifdef HAVE_ASSUME
+  for (i=1; i<n; i++)
+  {
+    assume(tc[i] >= 0);
+    assume(tc[i-1] + 1 <= tc[i]);
+  }
+#endif
+
+  omMemcpyW(sc, tc, n);
+  omFreeSize(tc, n*sizeof(long));
+  return new_space;
+}
+
+// this make a Setm on p
+static void pResetSetm(poly p)
+{
+#ifdef PDEBUG
+  poly q = p;
+#endif
+  while (p!= NULL)
+  {
+    pSetm(p);
+    pIter(p);
+  }
+#ifdef PDEBUG
+  if (! pTest(q))
+  {
+    pSetm(p);
+  }
+#endif
+}
+
+void syResetShiftedComponents(syStrategy syzstr, int index,int hilb)
+{
+  assume(index > 0);
+  int i;
+  if (syzstr->res[index] != NULL)
+  {
+    long * prev_s;
+    int* prev_c;
+    int p_length;
+    rGetSComps(&prev_c, &prev_s, &p_length);
+    currcomponents = syzstr->truecomponents[index-1];
+    currShiftedComponents = syzstr->ShiftedComponents[index-1];
+    rChangeSComps(currcomponents,
+                  currShiftedComponents,
+                  IDELEMS(syzstr->res[index-1]));
+    if (hilb==0)
+    {
+      ideal id = syzstr->res[index];
+      for (i=0; i<IDELEMS(id); i++)
+      {
+        pResetSetm(id->m[i]);
+      }
+    }
+    else if (hilb==1)
+    {
+      assume (index>1);
+      assume (syzstr->resPairs[index-1]!=NULL);
+      SSet Pairs=syzstr->resPairs[index-1];
+      SSet Pairs1=syzstr->resPairs[index];
+      int till=(*syzstr->Tl)[index-1];
+      for (i=0;i<till;i++)
+      {
+        if (Pairs[i].syz!=NULL)
+          pResetSetm(Pairs[i].syz);
+      }
+      till=(*syzstr->Tl)[index];
+      for (i=0;i<till;i++)
+      {
+        if (Pairs1[i].p!=NULL)
+          pResetSetm(Pairs1[i].p);
+      }
+    }
+    currcomponents  = prev_c;
+    currShiftedComponents = prev_s;
+    rChangeSComps(prev_c, prev_s, p_length);
+  }
+}
+
+/*3
+* determines the place of a polynomial in the right ordered resolution
+* set the vectors of truecomponents
+*/
+static BOOLEAN syOrder(poly p,syStrategy syzstr,int index,
+                    int realcomp)
+{
+  int i=IDELEMS(syzstr->res[index-1])+1,j=0,k,tc,orc,ie=realcomp-1;
+  int *trind1=syzstr->truecomponents[index-1];
+  int *trind=syzstr->truecomponents[index];
+  long *shind=syzstr->ShiftedComponents[index];
+  int *bc=syzstr->backcomponents[index];
+  int *F1=syzstr->Firstelem[index-1];
+  int *H1=syzstr->Howmuch[index-1];
+  poly pp;
+  polyset o_r=syzstr->orderedRes[index]->m;
+  polyset or1=syzstr->orderedRes[index-1]->m;
+  BOOLEAN ret = FALSE;
+
+  // if != 0, then new element can go into same component
+  // i.e., we do not need to leave space in shifted components
+  long same_comp = 0;
+
+  if (p==NULL) return FALSE;
+  if (realcomp==0) realcomp=1;
+
+  if (index>1)
+    tc = trind1[pGetComp(p)]-1;
+  else
+    tc = pGetComp(p)-1;
+  loop         //while ((j<ie) && (trind1[orc]<=tc+1))
+  {
+    if (j>=ie)
+      break;
+    else
+    {
+      orc = pGetComp(o_r[j]);
+      if (trind1[orc]>tc+1) break;
+      else if (trind1[orc] == tc+1)
+      {
+        same_comp = 1;
+      }
+      else
+      {
+        assume(same_comp == 0);
+      }
+      j += H1[orc];
+    }
+  }
+  if (j>ie)
+  {
+    WerrorS("orderedRes to small");
+    return FALSE;
+  }
+  ie++;
+  if (j == (ie -1))
+  {
+    // new element is the last in ordered module
+    if (same_comp == 0)
+      same_comp = SYZ_SHIFT_BASE;
+
+    // test wheter we have enough space for new shifted component
+    if ((LONG_MAX - same_comp) <= shind[ie-1])
+    {
+      long new_space = syReorderShiftedComponents(shind, ie);
+      assume((LONG_MAX - same_comp) > shind[ie-1]);
+      ret = TRUE;
+      if (TEST_OPT_PROT) Print("(T%u)", new_space);
+    }
+
+    // yes, then set new shifted component
+    assume(ie == 1 || shind[ie-1] > 0);
+    shind[ie] = shind[ie-1] + same_comp;
+  }
+  else
+  {
+    // new element must come in between
+    // i.e. at place j+1
+    long prev, next;
+
+    // test whether new component can get shifted value
+    prev = shind[j];
+    next = shind[j+1];
+    assume(next > prev);
+    if ((same_comp && prev + 2 >= next) || (!same_comp && next - prev < 4))
+    {
+       long new_space = syReorderShiftedComponents(shind, ie);
+      prev = shind[j];
+      next = shind[j+1];
+      assume((same_comp && prev + 2 < next) || (!same_comp && next - prev >= 4));
+      ret = TRUE;
+     if (TEST_OPT_PROT) Print("(B%u)", new_space);
+    }
+
+    // make room for insertion of j+1 shifted component
+    for (k=ie; k > j+1; k--) shind[k] = shind[k-1];
+
+    if (same_comp)
+    {
+      // can simply add one
+      shind[j+1] = prev + 1;
+      assume(shind[j+1] + 1 < shind[j+2]);
+    }
+    else
+    {
+      // need to leave more breathing room - i.e. value goes in
+      // between
+      shind[j+1]  = prev + ((next - prev) >> 1);
+      assume (shind[j] + 1 < shind[j+1] && shind[j+1] + 1 < shind[j+2]);
+    }
+  }
+
+  if (o_r[j]!=NULL)
+  {
+    for (k=ie-1;k>j;k--)
+    {
+      o_r[k] = o_r[k-1];
+      bc[k] = bc[k-1];
+    }
+  }
+  o_r[j] = p;
+  bc[j] = realcomp-1;
+  (H1[pGetComp(p)])++;
+  for (k=0;k<i;k++)
+  {
+    if (F1[k]>j)
+      (F1[k])++;
+  }
+  if (F1[pGetComp(p)]==0)
+    F1[pGetComp(p)]=j+1;
+  for (k=0;k<IDELEMS((syzstr->res)[index]);k++)
+  {
+    if (trind[k]>j)
+      trind[k] += 1;
+  }
+  for (k=IDELEMS((syzstr->res)[index])-1;k>realcomp;k--)
+    trind[k] = trind[k-1];
+  trind[realcomp] = j+1;
+  return ret;
+}
+
+//#define OLD_PAIR_ORDER
+#ifdef OLD_PAIR_ORDER
+static intvec* syLinStrat(SSet nextPairs, syStrategy syzstr,
+                          int howmuch, int index)
+{
+  int i=howmuch-1,i1=0,l,ll;
+  int ** Fin=syzstr->Firstelem;
+  int ** Hin=syzstr->Howmuch;
+  int ** bin=syzstr->backcomponents;
+  ideal o_r=syzstr->orderedRes[index+1];
+  intvec *result=new intvec(howmuch+1);
+  BOOLEAN isDivisible;
+  SObject tso;
+
+  while (i>=0)
+  {
+    tso = nextPairs[i];
+    isDivisible = FALSE;
+    if (syzstr->res[index+1]!=NULL)
+    {
+      l = Fin[index][pGetComp(tso.lcm)]-1;
+      if (l>=0)
+      {
+        ll = l+Hin[index][pGetComp(tso.lcm)];
+        while ((l<ll) && (!isDivisible))
+        {
+          if (o_r->m[l]!=NULL)
+          {
+            isDivisible = isDivisible ||
+              pLmDivisibleByNoComp(o_r->m[l],tso.lcm);
+          }
+          l++;
+        }
+      }
+    }
+    if (isDivisible)
+    {
+      syDeletePair(&nextPairs[i]);
+      //crit++;
+    }
+    else
+    {
+      nextPairs[i].p =
+        //sySPoly(tso.p1, tso.p2,tso.lcm);
+        spSpolyCreate(tso.p2, tso.p1,NULL,spSpolyLoop_General);
+      (*result)[i1] = i+1;
+      i1++;
+    }
+    i--;
+  }
+  return result;
+}
+#else
+static intvec* syLinStrat(SSet nextPairs, syStrategy syzstr,
+                          int howmuch, int index)
+{
+  int i=howmuch-1,i1=0,i2,i3,l,ll;
+  int ** Fin=syzstr->Firstelem;
+  int ** Hin=syzstr->Howmuch;
+  int ** bin=syzstr->backcomponents;
+  ideal o_r=syzstr->orderedRes[index+1];
+  intvec *result=new intvec(howmuch+1);
+  intvec *spl=new intvec(howmuch,1,-1);
+  BOOLEAN isDivisible;
+  SObject tso;
+
+  while (i>=0)
+  {
+    tso = nextPairs[i];
+    isDivisible = FALSE;
+    if (syzstr->res[index+1]!=NULL)
+    {
+      l = Fin[index][pGetComp(tso.lcm)]-1;
+      if (l>=0)
+      {
+        ll = l+Hin[index][pGetComp(tso.lcm)];
+        while ((l<ll) && (!isDivisible))
+        {
+          if (o_r->m[l]!=NULL)
+          {
+            isDivisible = isDivisible ||
+              pLmDivisibleByNoComp(o_r->m[l],tso.lcm);
+          }
+          l++;
+        }
+      }
+    }
+    if (isDivisible)
+    {
+      syDeletePair(&nextPairs[i]);
+      //crit++;
+    }
+    else
+    {
+      pTest(tso.p2);
+      pTest(tso.p1);
+      nextPairs[i].p =
+        ksOldCreateSpoly(tso.p2, tso.p1,NULL);
+      (*spl)[i] = pLength(nextPairs[i].p);
+    }
+    i--;
+  }
+  i3 = 0;
+  loop
+  {
+    i2 = -1;
+    for (i1=0;i1<howmuch;i1++)
+    {
+      if (i2==-1)
+      {
+        if ((*spl)[i1]!=-1)
+        {
+          i2 = i1;
+        }
+      }
+      else
+      {
+        if (((*spl)[i1]>=0) && ((*spl)[i1]<(*spl)[i2]))
+        {
+          i2 = i1;
+        }
+      }
+    }
+    if (i2>=0)
+    {
+      (*result)[i3] = i2+1;
+      (*spl)[i2] = -1;
+      i3++;
+    }
+    else
+    {
+      break;
+    }
+  }
+  delete spl;
+  return result;
+}
+#endif
+
+void syEnlargeFields(syStrategy syzstr,int index)
+{
+  pEnlargeSet(&(syzstr->res[index]->m),IDELEMS(syzstr->res[index]),16);
+  syzstr->truecomponents[index]=(int*)omRealloc0Size((ADDRESS)syzstr->truecomponents[index],
+                               (IDELEMS(syzstr->res[index])+1)*sizeof(int),
+                               (IDELEMS(syzstr->res[index])+17)*sizeof(int));
+  syzstr->ShiftedComponents[index]
+    =(long*)omRealloc0Size((ADDRESS)syzstr->ShiftedComponents[index],
+                              (IDELEMS(syzstr->res[index])+1)*sizeof(long),
+                              (IDELEMS(syzstr->res[index])+17)*sizeof(long));
+  syzstr->backcomponents[index]=(int*)omRealloc0Size((ADDRESS)syzstr->backcomponents[index],
+                               (IDELEMS(syzstr->res[index])+1)*sizeof(int),
+                               (IDELEMS(syzstr->res[index])+17)*sizeof(int));
+  syzstr->Howmuch[index]=(int*)omRealloc0Size((ADDRESS)syzstr->Howmuch[index],
+                               (IDELEMS(syzstr->res[index])+1)*sizeof(int),
+                               (IDELEMS(syzstr->res[index])+17)*sizeof(int));
+  syzstr->Firstelem[index]=(int*)omRealloc0Size((ADDRESS)syzstr->Firstelem[index],
+                               (IDELEMS(syzstr->res[index])+1)*sizeof(int),
+                               (IDELEMS(syzstr->res[index])+17)*sizeof(int));
+  syzstr->elemLength[index]=(int*)omRealloc0Size((ADDRESS)syzstr->elemLength[index],
+                               (IDELEMS(syzstr->res[index])+1)*sizeof(int),
+                               (IDELEMS(syzstr->res[index])+17)*sizeof(int));
+  syzstr->sev[index]=(unsigned long*)omRealloc0Size((ADDRESS)syzstr->sev[index],
+                                    (IDELEMS(syzstr->res[index])+1)*sizeof(unsigned long),
+                               (IDELEMS(syzstr->res[index])+17)*sizeof(unsigned long));
+  IDELEMS(syzstr->res[index]) += 16;
+  pEnlargeSet(&(syzstr->orderedRes[index]->m),IDELEMS(syzstr->orderedRes[index]),16);
+  IDELEMS(syzstr->orderedRes[index]) += 16;
+}
+/*3
+* reduces all pairs of degree deg in the module index
+* put the reduced generators to the resolvente which contains
+* the truncated kStd
+*/
+static void syRedNextPairs(SSet nextPairs, syStrategy syzstr,
+               int howmuch, int index)
+{
+  int i,j,k=IDELEMS(syzstr->res[index]);
+  int ks=IDELEMS(syzstr->res[index+1]),kk,l,ll;
+  int * Fin=syzstr->Firstelem[index-1];
+  int * Hin=syzstr->Howmuch[index-1];
+  int * bin=syzstr->backcomponents[index];
+  int * elL=syzstr->elemLength[index];
+  number coefgcd,n;
+  polyset redset=syzstr->orderedRes[index]->m;
+  poly p=NULL,q;
+  intvec *spl1;
+  SObject tso;
+  long * ShiftedComponents = syzstr->ShiftedComponents[index];
+  int* Components = syzstr->truecomponents[index];
+  assume(Components != NULL && ShiftedComponents != NULL);
+  BOOLEAN need_reset;
+
+  if ((nextPairs==NULL) || (howmuch==0)) return;
+  while ((k>0) && (syzstr->res[index]->m[k-1]==NULL)) k--;
+  while ((ks>0) && (syzstr->res[index+1]->m[ks-1]==NULL)) ks--;
+  spl1 = syLinStrat(nextPairs,syzstr,howmuch,index);
+  i=0;
+  while ((*spl1)[i]>0)
+  {
+    need_reset = FALSE;
+    tso = nextPairs[(*spl1)[i]-1];
+    if ((tso.p1!=NULL) && (tso.p2!=NULL))
+    {
+      nNormalize(pGetCoeff(tso.p1));
+      nNormalize(pGetCoeff(tso.p2));
+      coefgcd =
+        nGcd(pGetCoeff(tso.p1),pGetCoeff(tso.p2),currRing);
+      tso.syz = pHead(tso.lcm);
+      p = tso.syz;
+      pSetCoeff(p,nDiv(pGetCoeff(tso.p1),coefgcd));
+      pGetCoeff(p) = nNeg(pGetCoeff(p));
+      pSetComp(p,tso.ind2+1);
+      p_Setm_Syz(p, currRing, Components, ShiftedComponents); // actueller index
+      pNext(p) = pHead(tso.lcm);
+      pIter(p);
+      pSetComp(p,tso.ind1+1);
+      p_Setm_Syz(p, currRing, Components, ShiftedComponents); // actueller index
+      pSetCoeff(p,nDiv(pGetCoeff(tso.p2),coefgcd));
+      nDelete(&coefgcd);
+      if (tso.p != NULL)
+      {
+        kBucketInit(syzstr->bucket,tso.p,-1);
+        q = kBucketGetLm(syzstr->bucket);
+        j = Fin[pGetComp(q)]-1;
+        int pos = j+Hin[pGetComp(q)];
+        loop
+        {
+          if (j<0) break;
+          if (pLmDivisibleByNoComp(redset[j],q))
+          {
+            pNext(p) = pHead(q);
+            pIter(p);
+            pSetComp(p,bin[j]+1);
+            p_Setm_Syz(p, currRing, Components, ShiftedComponents); // actueller index
+//if (pLength(redset[j])!=syzstr->elemLength[index][bin[j]])
+//Print("Halt");
+//if (pLength(redset[j])!=syzstr->elemLength[index][bin[j]])
+//Print("Halt");
+            pGetCoeff(p) = nNeg(pGetCoeff(p));
+            number up = kBucketPolyRed(syzstr->bucket,redset[j],elL[bin[j]],
+                                       NULL);
+            // Thomas: Check whether you need number here
+            nDelete(&up);
+            q = kBucketGetLm(syzstr->bucket);
+            if (q==NULL) break;
+            j = Fin[pGetComp(q)]-1;
+            pos = j+Hin[pGetComp(q)];
+          }
+          else
+          {
+            j++;
+            if (j==pos) break;
+          }
+        }
+        int lb;
+        kBucketClear(syzstr->bucket,&tso.p,&lb);
+      }
+      if (tso.p != NULL)
+      {
+        if (TEST_OPT_PROT) PrintS("g");
+        if (k==IDELEMS((syzstr->res)[index]))
+        {
+          syEnlargeFields(syzstr,index);
+          bin=syzstr->backcomponents[index];
+          elL=syzstr->elemLength[index];
+          redset=syzstr->orderedRes[index]->m;
+          Components = syzstr->truecomponents[index];
+          ShiftedComponents = syzstr->ShiftedComponents[index];
+        }
+        pNext(p) = pHead(tso.p);
+        pIter(p);
+
+        assume(p!= NULL);
+        k++;
+        syzstr->res[index]->m[k-1] = tso.p;
+        syzstr->elemLength[index][k-1] = pLength(tso.p);
+        pNorm(syzstr->res[index]->m[k-1]);
+        need_reset = syOrder(syzstr->res[index]->m[k-1],syzstr,index,k);
+        pSetComp(p,k); // actueller index
+        p_Setm_Syz(p, currRing, Components, ShiftedComponents);
+        pGetCoeff(p) = nNeg(pGetCoeff(p));
+
+        tso.isNotMinimal = p;
+        tso.p = NULL;
+      }
+      else
+      {
+        if (TEST_OPT_PROT) PrintS(".");
+        //if (index % 2==0)
+          //euler++;
+        //else
+          //euler--;
+      }
+      if (ks==IDELEMS(syzstr->res[index+1]))
+      {
+        syEnlargeFields(syzstr,index+1);
+      }
+      syzstr->res[index+1]->m[ks] = tso.syz;
+      syzstr->elemLength[index+1][ks] = pLength(tso.syz);
+      pNorm(syzstr->res[index+1]->m[ks]);
+      tso.syz =NULL;
+      tso.syzind = ks;
+      if (need_reset)
+        syResetShiftedComponents(syzstr, index+1);
+      if (syOrder(syzstr->res[index+1]->m[ks],syzstr,index+1,ks+1))
+         syResetShiftedComponents(syzstr, index+2);
+      ks++;
+      p = NULL;
+      nextPairs[(*spl1)[i]-1] = tso;
+    }
+    i++;
+  }
+  delete spl1;
+}
+
+/*3
+* reduces the generators of the module index in degree deg
+* (which are actual syzygies of the module index-1)
+* wrt. the ideal generated by elements of lower degrees
+*/
+static void syRedGenerOfCurrDeg(syStrategy syzstr, int deg, int index)
+{
+  ideal res=syzstr->res[index];
+  int i=0,j,k=IDELEMS(res),kk;
+  SSet sPairs=syzstr->resPairs[index-1];
+
+  while ((k>0) && (res->m[k-1]==NULL)) k--;
+  while ((i<(*syzstr->Tl)[index-1]) && (((sPairs)[i].syz==NULL) ||
+          ((sPairs)[i].order<deg)))
+    i++;
+  if ((i>=(*syzstr->Tl)[index-1]) || ((sPairs)[i].order>deg)) return;
+  while ((i<(*syzstr->Tl)[index-1]) && (((sPairs)[i].syz==NULL) ||
+         ((sPairs)[i].order==deg)))
+  {
+    if ((sPairs)[i].syz!=NULL)
+    {
+      j = k-1;
+      while ((j>=0) && (res->m[j]!=NULL) &&
+             ((sPairs)[i].syz!=NULL))
+      {
+        if (pLmDivisibleBy(res->m[j],(sPairs)[i].syz))
+        {
+          (sPairs)[i].syz =
+            ksOldSpolyRed(res->m[j],(sPairs)[i].syz);
+            //sySPolyRed((sPairs)[i].syz,res->m[j]);
+          j = k-1;
+        }
+        else
+        {
+          j--;
+        }
+      }
+      if ((sPairs)[i].syz != NULL)
+      {
+        if (k==IDELEMS(res))
+        {
+          syEnlargeFields(syzstr,index);
+          res=syzstr->res[index];
+        }
+        if (TEST_OPT_DEBUG)
+        {
+          if ((sPairs)[i].isNotMinimal==NULL)
+          {
+            PrintLn();
+            PrintS("minimal generator: ");pWrite((syzstr->resPairs[index-1])[i].syz);
+            PrintS("comes from: ");pWrite((syzstr->resPairs[index-1])[i].p1);
+            PrintS("and: ");pWrite((syzstr->resPairs[index-1])[i].p2);
+          }
+        }
+        //res->m[k] = (sPairs)[i].syz;
+        res->m[k] = syRedtail((sPairs)[i].syz,syzstr,index);
+        (sPairs)[i].syzind = k;
+        syzstr->elemLength[index][k] = pLength((sPairs)[i].syz);
+        pNorm(res->m[k]);
+  //      (sPairs)[i].syz = NULL;
+        k++;
+        if (syOrder(res->m[k-1],syzstr,index,k))
+          syResetShiftedComponents(syzstr, index);
+        //euler++;
+      }
+      else
+        (sPairs)[i].syzind = -1;
+    }
+    i++;
+  }
+}
+
+/*3
+* puts a pair into the right place in resPairs
+*/
+void syEnterPair(SSet sPairs, SObject * so, int * sPlength,int index)
+{
+  int ll,k,no=(*so).order,sP=*sPlength,i;
+  poly p=(*so).lcm;
+
+  if ((sP==0) || (sPairs[sP-1].order<=no))
+    ll = sP;
+  else if (sP==1)
+    ll = 0;
+  else
+  {
+    int an=0,en=sP-1;
+    loop
+    {
+      if (an>=en-1)
+      {
+        if ((sPairs[an].order<=no) && (sPairs[an+1].order>no))
+        {
+          ll = an+1;
+          break;
+        }
+        else if ((sPairs[en].order<=no) && (sPairs[en+1].order>no))
+        {
+          ll = en+1;
+          break;
+        }
+        else if (sPairs[an].order>no)
+        {
+          ll = an;
+          break;
+        }
+        else
+        {
+          PrintS("Hier ist was faul!\n");
+          break;
+        }
+      }
+      i=(an+en) / 2;
+      if (sPairs[i].order <= no)
+        an=i;
+      else
+        en=i;
+    }
+  }
+  for (k=(*sPlength);k>ll;k--)
+  {
+    syCopyPair(&sPairs[k-1],&sPairs[k]);
+  }
+  syCopyPair(so,&sPairs[ll]);
+  (*sPlength)++;
+}
+void syEnterPair(syStrategy syzstr, SObject * so, int * sPlength,int index)
+{
+  int ll;
+
+  if (*sPlength>=(*syzstr->Tl)[index])
+  {
+    SSet temp = (SSet)omAlloc0(((*syzstr->Tl)[index]+16)*sizeof(SObject));
+    for (ll=0;ll<(*syzstr->Tl)[index];ll++)
+    {
+      temp[ll].p = (syzstr->resPairs[index])[ll].p;
+      temp[ll].p1 = (syzstr->resPairs[index])[ll].p1;
+      temp[ll].p2 = (syzstr->resPairs[index])[ll].p2;
+      temp[ll].syz = (syzstr->resPairs[index])[ll].syz;
+      temp[ll].lcm = (syzstr->resPairs[index])[ll].lcm;
+      temp[ll].ind1 = (syzstr->resPairs[index])[ll].ind1;
+      temp[ll].ind2 = (syzstr->resPairs[index])[ll].ind2;
+      temp[ll].syzind = (syzstr->resPairs[index])[ll].syzind;
+      temp[ll].order = (syzstr->resPairs[index])[ll].order;
+      temp[ll].isNotMinimal = (syzstr->resPairs[index])[ll].isNotMinimal;
+      temp[ll].length = (syzstr->resPairs[index])[ll].length;
+      temp[ll].reference = (syzstr->resPairs[index])[ll].reference;
+    }
+    if (syzstr->resPairs[index] != NULL) // OB: ?????
+      omFreeSize((ADDRESS)syzstr->resPairs[index],(*syzstr->Tl)[index]*sizeof(SObject));
+    (*syzstr->Tl)[index] += 16;
+    syzstr->resPairs[index] = temp;
+  }
+  syEnterPair(syzstr->resPairs[index],so,sPlength,index);
+}
+
+/*3
+* computes pairs from the new elements (beginning with the element newEl)
+* in the module index
+*/
+static void syCreateNewPairs(syStrategy syzstr, int index, int newEl)
+{
+  SSet temp;
+  SObject tso;
+  int i,ii,j,k=IDELEMS(syzstr->res[index]),l=(*syzstr->Tl)[index],ll;
+  int qc,first,pos,jj,j1;
+  int * bci=syzstr->backcomponents[index];
+  poly p,q;
+  polyset rs=syzstr->res[index]->m,nPm;
+
+
+  while ((k>0) && (rs[k-1]==NULL)) k--;
+  if (newEl>=k) return;
+
+  long * ShiftedComponents = syzstr->ShiftedComponents[index];
+  int* Components = syzstr->truecomponents[index];
+
+  ideal nP=idInit(k,syzstr->res[index]->rank);
+  nPm=nP->m;
+  while ((l>0) && ((syzstr->resPairs[index])[l-1].p1==NULL)) l--;
+  for (j=newEl;j<k;j++)
+  {
+    q = rs[j];
+    qc = pGetComp(q);
+    first = syzstr->Firstelem[index-1][pGetComp(q)]-1;
+    pos = first+syzstr->Howmuch[index-1][pGetComp(q)];
+    for (i=first;i<pos;i++)
+    {
+      jj = bci[i];
+      if (jj>=j) break;
+      p = pOne();
+      pLcm(rs[jj],q,p);
+      pSetComp(p,j+1);
+      p_Setm_Syz(p, currRing, Components, ShiftedComponents);
+      ii = first;
+      loop
+      {
+        j1 = bci[ii];
+        if (nPm[j1]!=NULL)
+        {
+          if (pLmDivisibleByNoComp(nPm[j1],p))
+          {
+            pDelete(&p);
+            break;
+          }
+          else if (pLmDivisibleByNoComp(p,nPm[j1]))
+          {
+            pDelete(&(nPm[j1]));
+            //break;
+          }
+        }
+        ii++;
+        if (ii>=pos) break;
+      }
+      if (p!=NULL)
+      {
+        nPm[jj] = p;
+      }
+    }
+    for (i=first;i<pos;i++)
+    {
+      ii = bci[i];
+      if (nPm[ii]!=NULL)
+      {
+        if (l>=(*syzstr->Tl)[index])
+        {
+          temp = (SSet)omAlloc0(((*syzstr->Tl)[index]+16)*sizeof(SObject));
+          for (ll=0;ll<(*syzstr->Tl)[index];ll++)
+          {
+            temp[ll].p = (syzstr->resPairs[index])[ll].p;
+            temp[ll].p1 = (syzstr->resPairs[index])[ll].p1;
+            temp[ll].p2 = (syzstr->resPairs[index])[ll].p2;
+            temp[ll].syz = (syzstr->resPairs[index])[ll].syz;
+            temp[ll].lcm = (syzstr->resPairs[index])[ll].lcm;
+            temp[ll].ind1 = (syzstr->resPairs[index])[ll].ind1;
+            temp[ll].ind2 = (syzstr->resPairs[index])[ll].ind2;
+            temp[ll].syzind = (syzstr->resPairs[index])[ll].syzind;
+            temp[ll].order = (syzstr->resPairs[index])[ll].order;
+            temp[ll].isNotMinimal = (syzstr->resPairs[index])[ll].isNotMinimal;
+          }
+          if (syzstr->resPairs[index] != NULL) // OB: ????
+            omFreeSize((ADDRESS)syzstr->resPairs[index],(*syzstr->Tl)[index]*sizeof(SObject));
+          (*syzstr->Tl)[index] += 16;
+          syzstr->resPairs[index] = temp;
+        }
+        tso.lcm = p = nPm[ii];
+        nPm[ii] = NULL;
+        //#ifdef HAVE_SHIFTED_EXPONENTS
+        //tso.order = pTotaldegree(p);
+        //p->exp[currRing->pOrdIndex]=tso.order+0x40000000;
+        //#else
+        tso.order = pTotaldegree(p);
+        pSetOrder(p, tso.order);
+        //#endif
+        if ((syzstr->cw!=NULL) && (index>0) && (pGetComp(q)>0))
+        {
+          int ii=index-1,jj=pGetComp(q);
+          while (ii>0)
+          {
+            jj = pGetComp(syzstr->res[ii]->m[jj-1]);
+            ii--;
+          }
+          tso.order += (*syzstr->cw)[jj-1];
+        }
+        tso.p1 = rs[ii];
+        tso.p2 = q;
+        tso.ind1 = ii;
+        tso.ind2 = j;
+        tso.syzind = -1;
+        tso.isNotMinimal = NULL;
+        tso.p = NULL;
+        tso.syz = NULL;
+        syEnterPair(syzstr->resPairs[index],&tso,&l,index);
+      }
+    }
+  }
+  idDelete(&nP);
+}
+
+static SSet syChosePairsPutIn(syStrategy syzstr, int *index,
+               int *howmuch, int * actdeg, int an, int en)
+{
+  int newdeg=*actdeg,newindex=-1,i,t,sldeg;
+  poly p;
+  SSet result;
+  SRes resPairs=syzstr->resPairs;
+
+  if (an>syzstr->length) return NULL;
+  if (en>syzstr->length) en=syzstr->length;
+  while (*index<en)
+  {
+    if (resPairs[*index]!=NULL)
+    {
+      sldeg = (*actdeg)+*index;
+      i = 0;
+      if (*index!=0)
+      {
+        while ((i<(*syzstr->Tl)[*index]))
+        {
+          if ((resPairs[*index])[i].lcm!=NULL)
+          {
+            if ((resPairs[*index])[i].order == sldeg)
+            {
+              result = &(resPairs[*index])[i];
+              *howmuch =1;
+              i++;
+              while ((i<(*syzstr->Tl)[*index]) && ((resPairs[*index])[i].lcm!=NULL)
+                      && ((resPairs[*index])[i].order == sldeg))
+              {
+                i++;
+                (*howmuch)++;
+              }
+              return result;
+            }
+          }
+          i++;
+        }
+      }
+      else
+      {
+        while ((i<(*syzstr->Tl)[*index]))
+        {
+          if ((resPairs[*index])[i].syz!=NULL)
+          {
+            if ((resPairs[*index])[i].order == sldeg)
+            {
+              result = &(resPairs[*index])[i];
+              (*howmuch) =1;
+              i++;
+              while ((i<(*syzstr->Tl)[*index]) && ((resPairs[*index])[i].syz!=NULL)
+                      && ((resPairs[*index])[i].order == *actdeg))
+              {
+                i++;
+                (*howmuch)++;
+              }
+              return result;
+            }
+          }
+          i++;
+        }
+      }
+    }
+    (*index)++;
+  }
+  *index = an;
+  //if (TEST_OPT_PROT) Print("(Euler:%d)",euler);
+  while (*index<en)
+  {
+    if (resPairs[*index]!=NULL)
+    {
+      i = 0;
+      while ((i<(*syzstr->Tl)[*index]))
+      {
+        t = *actdeg+*index;
+        if (((resPairs[*index])[i].lcm!=NULL) ||
+              ((resPairs[*index])[i].syz!=NULL))
+        {
+          if ((resPairs[*index])[i].order > t)
+            t = (resPairs[*index])[i].order;
+        }
+        if ((t>*actdeg+*index) && ((newdeg==*actdeg) || (t<newdeg+*index)))
+        {
+          newdeg = t-*index;
+          newindex = *index;
+          break;
+        }
+        i++;
+      }
+    }
+    (*index)++;
+  }
+  if (newdeg>*actdeg)
+  {
+    *actdeg = newdeg;
+    *index = newindex;
+    return syChosePairsPutIn(syzstr,index,howmuch,actdeg,an,en);
+  }
+  else return NULL;
+}
+
+/*3
+* FOR THE HOMOGENEOUS CASE ONLY!
+* looks through the pair set and the given module for
+* remaining pairs or generators to consider
+* returns a pointer to the first pair and the number of them in the given module
+* works with slanted degree (i.e. deg=realdeg-index)
+*/
+SSet syChosePairs(syStrategy syzstr, int *index, int *howmuch, int * actdeg)
+{
+  return syChosePairsPutIn(syzstr,index,howmuch,actdeg,0,syzstr->length);
+}
+
+/*3
+* FOR THE INHOMOGENEOUS CASE ONLY!
+* looks through the pair set and the given module for
+* remaining pairs or generators to consider
+* returns a pointer to the first pair and the number of them in the given module
+* works with slanted degree (i.e. deg=realdeg-index)
+* looks first through the 0 and 1 module then through the other
+*/
+static SSet syChosePairsIH(syStrategy syzstr, int *index,
+               int *howmuch, int * actdeg, int mindeg)
+{
+  SSet result=NULL;
+
+  result = syChosePairsPutIn(syzstr,index,howmuch,actdeg,0,2);
+  if (result == NULL)
+  {
+    *actdeg = mindeg;
+    result = syChosePairsPutIn(syzstr,index,howmuch,actdeg,2,syzstr->length);
+  }
+  return result;
+}
+
+/*3
+* looks through the pair set and the given module for
+* remaining pairs or generators to consider
+* returns a pointer to the first pair and the number of them in the given module
+* works deg by deg
+*/
+/*
+*static SSet syChosePairs1(SRes resPairs,intvec * Tl, int *index, int *howmuch,
+*                   int length,int * actdeg)
+*{
+*  int newdeg=*actdeg,newindex=-1,i,t;
+*  SSet result;
+*
+*  while (*index>=0)
+*  {
+*    if (resPairs[*index]!=NULL)
+*    {
+*      i = 0;
+*      if (*index!=0)
+*      {
+*        while ((i<(*Tl)[*index]))
+*        {
+*          if ((resPairs[*index])[i].lcm!=NULL)
+*          {
+*            if (pGetOrder((resPairs[*index])[i].lcm) == *actdeg)
+*            {
+*              result = &(resPairs[*index])[i];
+*              *howmuch =1;
+*              i++;
+*              while ((i<(*Tl)[*index]) && ((resPairs[*index])[i].lcm!=NULL)
+*                      && (pGetOrder((resPairs[*index])[i].lcm) == *actdeg))
+*              {
+*                i++;
+*                (*howmuch)++;
+*              }
+*              return result;
+*            }
+*          }
+*          i++;
+*        }
+*      }
+*      else
+*      {
+*        while ((i<(*Tl)[*index]))
+*        {
+*          if ((resPairs[*index])[i].syz!=NULL)
+*          {
+*            if ((resPairs[*index])[i].order == *actdeg)
+*            {
+*              result = &(resPairs[*index])[i];
+*              (*howmuch) =1;
+*              i++;
+*              while ((i<(*Tl)[*index]) && ((resPairs[*index])[i].syz!=NULL)
+*                      && ((resPairs[*index])[i].order == *actdeg))
+*              {
+*                i++;
+*                (*howmuch)++;
+*              }
+*              return result;
+*            }
+*          }
+*          i++;
+*        }
+*      }
+*    }
+*    (*index)--;
+*  }
+*  *index = length-1;
+*  while (*index>=0)
+*  {
+*    if (resPairs[*index]!=NULL)
+*    {
+*      i = 0;
+*      while ((i<(*Tl)[*index]))
+*      {
+*        t = *actdeg;
+*        if ((resPairs[*index])[i].lcm!=NULL)
+*        {
+*          if (pGetOrder((resPairs[*index])[i].lcm) > *actdeg)
+*            t = pGetOrder((resPairs[*index])[i].lcm);
+*        }
+*        else if ((resPairs[*index])[i].syz!=NULL)
+*        {
+*          if ((resPairs[*index])[i].order > *actdeg)
+*            t = (resPairs[*index])[i].order;
+*        }
+*        if ((t>*actdeg) && ((newdeg==*actdeg) || (t<newdeg)))
+*        {
+*          newdeg = t;
+*          newindex = *index;
+*          break;
+*        }
+*        i++;
+*      }
+*    }
+*    (*index)--;
+*  }
+*  if (newdeg>*actdeg)
+*  {
+*    *actdeg = newdeg;
+*    *index = newindex;
+*    return syChosePairs1(resPairs,Tl,index,howmuch,length,actdeg);
+*  }
+*  else return NULL;
+*}
+*/
+/*3
+* statistics of the resolution
+*/
+static void syStatistics(resolvente res,int length)
+{
+  int i,j=1,k;
+  Order_t deg = 0;
+
+  PrintLn();
+  while ((j<length) && (res[j]!=NULL))
+  {
+    Print("In module %d: \n",j);
+    k = 0;
+    while ((k<IDELEMS(res[j])) && (res[j]->m[k]!=NULL))
+    {
+      i = 1;
+      deg = pGetOrder(res[j]->m[k]);
+      k++;
+      while ((k<IDELEMS(res[j])) && (res[j]->m[k]!=NULL) &&
+              (pGetOrder(res[j]->m[k])==deg))
+      {
+        i++;
+        k++;
+      }
+      Print("%d elements of degree %d\n",i,deg);
+    }
+    j++;
+  }
+}
+
+/*3
+* initialize a module
+*/
+int syInitSyzMod(syStrategy syzstr, int index, int init)
+{
+  int result;
+
+  if (syzstr->res[index]==NULL)
+  {
+    syzstr->res[index] = idInit(init-1,1);
+    syzstr->truecomponents[index] = (int*)omAlloc0(init*sizeof(int));
+    syzstr->ShiftedComponents[index] = (long*)omAlloc0(init*sizeof(long));
+    if (index==0)
+    {
+      for (int i=0;i<init;i++)
+      {
+        syzstr->truecomponents[0][i] = i;
+        syzstr->ShiftedComponents[0][i] = (i)*SYZ_SHIFT_BASE;
+      }
+    }
+    syzstr->backcomponents[index] = (int*)omAlloc0(init*sizeof(int));
+    syzstr->Howmuch[index] = (int*)omAlloc0(init*sizeof(int));
+    syzstr->Firstelem[index] = (int*)omAlloc0(init*sizeof(int));
+    syzstr->elemLength[index] = (int*)omAlloc0(init*sizeof(int));
+    syzstr->orderedRes[index] = idInit(init-1,1);
+    syzstr->sev[index] = (unsigned long*) omAlloc0(init*sizeof(unsigned long));
+    result = 0;
+  }
+  else
+  {
+    result = IDELEMS(syzstr->res[index]);
+    while ((result>0) && (syzstr->res[index]->m[result-1]==NULL)) result--;
+  }
+  return result;
+}
+
+/*3
+* deletes a resolution
+*/
+void syKillComputation(syStrategy syzstr, ring r)
+{
+  if (syzstr->references>0)
+  {
+    (syzstr->references)--;
+  }
+  else
+  {
+    int i,j;
+    if (syzstr->minres!=NULL)
+    {
+      for (i=0;i<syzstr->length;i++)
+      {
+        if (syzstr->minres[i]!=NULL)
+        {
+          for (j=0;j<IDELEMS(syzstr->minres[i]);j++)
+          {
+            if (syzstr->minres[i]->m[j]!=NULL)
+              p_Delete(&(syzstr->minres[i]->m[j]),r);
+          }
+        }
+        id_Delete(&(syzstr->minres[i]),r);
+      }
+      omFreeSize((ADDRESS)syzstr->minres,(syzstr->length+1)*sizeof(ideal));
+    }
+    if (syzstr->fullres!=NULL)
+    {
+      for (i=0;i<syzstr->length;i++)
+      {
+        if (syzstr->fullres[i]!=NULL)
+        {
+          for (j=0;j<IDELEMS(syzstr->fullres[i]);j++)
+          {
+            if (syzstr->fullres[i]->m[j]!=NULL)
+              p_Delete(&(syzstr->fullres[i]->m[j]),r);
+          }
+        }
+        id_Delete(&(syzstr->fullres[i]),r);
+      }
+      omFreeSize((ADDRESS)syzstr->fullres,(syzstr->length+1)*sizeof(ideal));
+    }
+    if (syzstr->weights!=0)
+    {
+      for (i=0;i<syzstr->length;i++)
+      {
+        if (syzstr->weights[i]!=NULL)
+        {
+          delete syzstr->weights[i];
+        }
+      }
+      omFreeSize((ADDRESS)syzstr->weights,syzstr->length*sizeof(intvec*));
+    }
+
+    ring sr=syzstr->syRing;
+    if (sr==NULL) sr=r;
+
+    if (syzstr->resPairs!=NULL)
+    {
+      for (i=0;i<syzstr->length;i++)
+      {
+        for (j=0;j<(*syzstr->Tl)[i];j++)
+        {
+          if ((syzstr->resPairs[i])[j].lcm!=NULL)
+            p_Delete(&((syzstr->resPairs[i])[j].lcm),sr);
+          if ((i>0) && ((syzstr->resPairs[i])[j].syz!=NULL))
+            p_Delete(&((syzstr->resPairs[i])[j].syz),sr);
+        }
+        if (syzstr->orderedRes[i]!=NULL)
+        {
+          for (j=0;j<IDELEMS(syzstr->orderedRes[i]);j++)
+          {
+            syzstr->orderedRes[i]->m[j] = NULL;
+          }
+        }
+        id_Delete(&(syzstr->orderedRes[i]),sr);
+        if (syzstr->truecomponents[i]!=NULL)
+        {
+          omFreeSize((ADDRESS)syzstr->truecomponents[i],(IDELEMS(syzstr->res[i])+1)*sizeof(int));
+          syzstr->truecomponents[i]=NULL;
+          omFreeSize((ADDRESS)syzstr->ShiftedComponents[i],(IDELEMS(syzstr->res[i])+1)*sizeof(long));
+          syzstr->ShiftedComponents[i]=NULL;
+        }
+        if (syzstr->backcomponents[i]!=NULL)
+        {
+          omFreeSize((ADDRESS)syzstr->backcomponents[i],(IDELEMS(syzstr->res[i])+1)*sizeof(int));
+          syzstr->backcomponents[i]=NULL;
+        }
+        if (syzstr->Howmuch[i]!=NULL)
+        {
+          omFreeSize((ADDRESS)syzstr->Howmuch[i],(IDELEMS(syzstr->res[i])+1)*sizeof(int));
+          syzstr->Howmuch[i]=NULL;
+        }
+        if (syzstr->Firstelem[i]!=NULL)
+        {
+          omFreeSize((ADDRESS)syzstr->Firstelem[i],(IDELEMS(syzstr->res[i])+1)*sizeof(int));
+          syzstr->Firstelem[i]=NULL;
+        }
+        if (syzstr->elemLength[i]!=NULL)
+        {
+          omFreeSize((ADDRESS)syzstr->elemLength[i],(IDELEMS(syzstr->res[i])+1)*sizeof(int));
+          syzstr->elemLength[i]=NULL;
+        }
+        if (syzstr->res[i]!=NULL)
+        {
+          for (j=0;j<IDELEMS(syzstr->res[i]);j++)
+          {
+            if (syzstr->res[i]->m[j]!=NULL)
+              p_Delete(&(syzstr->res[i]->m[j]),sr);
+          }
+        }
+        if ((syzstr->hilb_coeffs!=NULL)
+        && (syzstr->hilb_coeffs[i]!=NULL))
+          delete syzstr->hilb_coeffs[i];
+        if (syzstr->sev[i] != NULL)
+          omFreeSize((ADDRESS)syzstr->sev[i], (IDELEMS(syzstr->res[i])+1)*sizeof(unsigned long));
+        id_Delete(&(syzstr->res[i]),sr);
+        if (syzstr->resPairs[i] != NULL) // OB: ????
+          omFreeSize((ADDRESS)syzstr->resPairs[i],(*syzstr->Tl)[i]*sizeof(SObject));
+      }
+      omFreeSize((ADDRESS)syzstr->resPairs,syzstr->length*sizeof(SObject*));
+      omFreeSize((ADDRESS)syzstr->res,(syzstr->length+1)*sizeof(ideal));
+      omFreeSize((ADDRESS)syzstr->orderedRes,(syzstr->length+1)*sizeof(ideal));
+      omFreeSize((ADDRESS)syzstr->elemLength,(syzstr->length+1)*sizeof(int*));
+      omFreeSize((ADDRESS)syzstr->truecomponents,(syzstr->length+1)*sizeof(int*));
+      omFreeSize((ADDRESS)syzstr->ShiftedComponents,(syzstr->length+1)*sizeof(long*));
+      if (syzstr->sev != NULL)
+        omFreeSize(((ADDRESS)syzstr->sev), (syzstr->length+1)*sizeof(unsigned long*));
+      omFreeSize((ADDRESS)syzstr->backcomponents,(syzstr->length+1)*sizeof(int*));
+      omFreeSize((ADDRESS)syzstr->Howmuch,(syzstr->length+1)*sizeof(int*));
+      omFreeSize((ADDRESS)syzstr->Firstelem,(syzstr->length+1)*sizeof(int*));
+      if (syzstr->hilb_coeffs!=NULL)
+        omFreeSize((ADDRESS)syzstr->hilb_coeffs,(syzstr->length+1)*sizeof(intvec*));
+    }
+    if (syzstr->cw!=NULL)
+      delete syzstr->cw;
+    if (syzstr->betti!=NULL)
+      delete syzstr->betti;
+    if (syzstr->resolution!=NULL)
+      delete syzstr->resolution;
+    if (syzstr->Tl!=NULL)
+      delete syzstr->Tl;
+    if ((syzstr->syRing != NULL) && (syzstr->syRing != r))
+    {
+      rKill(syzstr->syRing);
+    }
+    omFreeSize((ADDRESS)syzstr, sizeof(ssyStrategy));
+  }
+}
+
+/*3
+* read out the Betti numbers from resolution
+* (if not LaScala calls the traditional Betti procedure)
+*/
+intvec * syBettiOfComputation(syStrategy syzstr, BOOLEAN minim,int * row_shift)
+{
+  int dummy;
+  if (syzstr->betti!=NULL)
+  {
+    if (minim || (syzstr->resPairs!=NULL))
+      return ivCopy(syzstr->betti);
+  }
+  intvec *result;
+  if (syzstr->resPairs!=NULL)
+  {
+    int i,j=-1,jj=-1,l,sh=0;
+    SRes rP=syzstr->resPairs;
+
+    if (syzstr->hilb_coeffs!=NULL) sh = 1;
+    l = syzstr->length;
+    while ((l>0) && (rP[l-1]==NULL)) l--;
+    if (l==0) return NULL;
+    l--;
+    while (l>=sh)
+    {
+      i = 0;
+      while ((i<(*syzstr->Tl)[l]) &&
+        ((rP[l][i].lcm!=NULL) || (rP[l][i].syz!=NULL)))
+      {
+        if (rP[l][i].isNotMinimal==NULL)
+        {
+          if (j<rP[l][i].order-l)
+            j = rP[l][i].order-l;
+          if (jj<l)
+            jj = l;
+        }
+        i++;
+      }
+      l--;
+    }
+    j = j+sh;
+    jj = jj+2;
+    result=new intvec(j,jj-sh,0);
+    IMATELEM(*result,1,1)
+      = si_max(1,idRankFreeModule(syzstr->res[1],
+                               (syzstr->syRing!=NULL?syzstr->syRing:currRing)));
+    for (i=sh;i<jj;i++)
+    {
+      j = 0;
+      while (j<(*syzstr->Tl)[i])
+      {
+        if ((rP[i][j].isNotMinimal==NULL)&&
+           ((rP[i][j].lcm!=NULL) || (rP[i][j].syz!=NULL)))
+          IMATELEM(*result,rP[i][j].order-i+sh,i+2-sh)++;
+        j++;
+      }
+    }
+  }
+  else if (syzstr->fullres!=NULL)
+    result = syBetti(syzstr->fullres,syzstr->length,&dummy,NULL,minim,row_shift);
+  else
+    result = syBetti(syzstr->minres,syzstr->length,&dummy,NULL,minim,row_shift);
+  if ((minim) || (syzstr->resPairs!=NULL))
+    syzstr->betti = ivCopy(result);
+  return result;
+}
+
+/*3
+* computes the allocated length of the resolution
+*/
+int syLength(syStrategy syzstr)
+{
+  return syzstr->length;
+}
+
+/*3
+* computes the real length of the resolution
+*/
+int sySize(syStrategy syzstr)
+{
+  resolvente r=syzstr->res;
+  if (r==NULL)
+    r = syzstr->fullres;
+  if (r==NULL)
+    r = syzstr->minres;
+  if (r==NULL)
+  {
+    WerrorS("No resolution found");
+    return 0;
+  }
+  int i=syzstr->length;
+  while ((i>0) && (r[i-1]==NULL)) i--;
+  return i;
+}
+
+/*3
+* computes the cohomological dimension of res[1]
+*/
+int syDim(syStrategy syzstr)
+{
+  int i,j=-1,l;
+  if (syzstr->resPairs!=NULL)
+  {
+    SRes rP=syzstr->resPairs;
+
+    l = syzstr->length;
+    while ((l>0) && (rP[l-1]==NULL)) l--;
+    if (l==0) return -1;
+    l--;
+    while (l>=0)
+    {
+      i = 0;
+      while ((i<(*syzstr->Tl)[l]) &&
+        ((rP[l][i].lcm!=NULL) || (rP[l][i].syz!=NULL)) &&
+        (rP[l][i].isNotMinimal!=NULL))
+      {
+        i++;
+      }
+      if ((i<(*syzstr->Tl)[l]) &&
+        ((rP[l][i].lcm!=NULL) || (rP[l][i].syz!=NULL)) &&
+        (rP[l][i].isNotMinimal==NULL))
+        return l;
+      l--;
+    }
+    return l;
+  }
+  else
+    return sySize(syzstr);
+}
+
+/*3
+* copies the resolution (by increment the reference counter)
+*/
+syStrategy syCopy(syStrategy syzstr)
+{
+  syStrategy result=syzstr;
+  (result->references)++;
+  return result;
+}
+
+/*2
+* local print procedure used in syPrint
+*/
+static void syPrintEmptySpaces(int i)
+{
+  if (i!=0)
+  {
+    PrintS(" ");
+    syPrintEmptySpaces(i/10);
+  }
+}
+
+/*2
+* local print procedure used in syPrint
+*/
+static void syPrintEmptySpaces1(int i)
+{
+  if (i!=0)
+  {
+    PrintS(" ");
+    syPrintEmptySpaces1(i-1);
+  }
+}
+
+/*2
+* local print procedure used in syPrint
+*/
+static int syLengthInt(int i)
+{
+  int j=0;
+
+  if (i==0) return 1;
+  while (i!=0)
+  {
+    j++;
+    i = i/10;
+  }
+  return j;
+}
+
+/*3
+* prints the resolution as sequence of free modules
+*/
+void syPrint(syStrategy syzstr)
+{
+  if ((syzstr->resPairs==NULL) && (syzstr->fullres==NULL)
+     && (syzstr->minres==NULL))
+  {
+    PrintS("No resolution defined\n");
+    return;
+  }
+  int l=0;
+  if (syzstr->resolution==NULL)
+  {
+    int j;
+    if (syzstr->resPairs!=NULL)
+    {
+      syzstr->resolution = new intvec(syzstr->length+1);
+      SRes rP=syzstr->resPairs;
+      (*syzstr->resolution)[0]
+        = si_max(1,idRankFreeModule(syzstr->res[1],
+                                 (syzstr->syRing != NULL ? syzstr->syRing : currRing)));
+      while ((l<syzstr->length) && (rP[l]!=NULL))
+      {
+        j=0;
+        while ((j<(*syzstr->Tl)[l]) &&
+          ((rP[l][j].lcm!=NULL) || (rP[l][j].syz!=NULL)))
+        {
+          if (rP[l][j].isNotMinimal==NULL)
+            ((*syzstr->resolution)[l+1])++;
+          j++;
+        }
+        l++;
+      }
+    }
+    else
+    {
+      resolvente rr;
+      syzstr->resolution = new intvec(syzstr->length+2);
+      if (syzstr->minres!=NULL)
+        rr = syzstr->minres;
+      else
+        rr = syzstr->fullres;
+      (*syzstr->resolution)[0]
+        = si_max(1,idRankFreeModule(rr[0],
+                                 (syzstr->syRing != NULL ? syzstr->syRing : currRing)));
+      while ((l<syzstr->length) && (rr[l]!=NULL))
+      {
+        j = IDELEMS(rr[l]);
+        while ((j>0) && (rr[l]->m[j-1]==NULL)) j--;
+        ((*syzstr->resolution)[l+1]) = j;
+        l++;
+      }
+    }
+  }
+  char *sn=currRingHdl->id;
+  int sl=strlen(sn);
+  syPrintEmptySpaces1(sl);
+  l = 0;
+  loop
+  {
+    Print("%d",(*syzstr->resolution)[l]);
+    if ((l>=syzstr->resolution->length()) || ((*syzstr->resolution)[l]==0))
+      break;
+    syPrintEmptySpaces1(sl+5);
+    l++;
+  }
+  PrintLn();
+  l = 0;
+  loop
+  {
+    Print(sn);
+    if ((l>=syzstr->resolution->length()) || ((*syzstr->resolution)[l]==0))
+      break;
+    syPrintEmptySpaces((*syzstr->resolution)[l]);
+    PrintS(" <-- ");
+    l++;
+  }
+  PrintLn();
+  PrintLn();
+  l = 0;
+  loop
+  {
+    Print("%d",l);
+    if ((l>=syzstr->resolution->length()) || ((*syzstr->resolution)[l]==0))
+      break;
+    syPrintEmptySpaces1(sl+5+syLengthInt((*syzstr->resolution)[l])-
+                         syLengthInt(l));
+    l++;
+  }
+  PrintLn();
+  if (syzstr->minres==NULL)
+  {
+    PrintS("resolution not minimized yet");
+    PrintLn();
+  }
+}
+
+/*2
+* divides out the weight monomials (given by the Schreyer-ordering)
+* from the LaScala-resolution
+*/
+resolvente syReorder(resolvente res,int length,
+        syStrategy syzstr,BOOLEAN toCopy=TRUE,resolvente totake=NULL)
+{
+  int i,j,l;
+  poly p,q,tq;
+  polyset ri1;
+  resolvente fullres;
+  ring origR=syzstr->syRing;
+  fullres = (resolvente)omAlloc0((length+1)*sizeof(ideal));
+  if (totake==NULL)
+    totake = res;
+  for (i=length-1;i>0;i--)
+  {
+    if (res[i]!=NULL)
+    {
+      if (i>1)
+      {
+        j = IDELEMS(res[i-1]);
+        while ((j>0) && (res[i-1]->m[j-1]==NULL)) j--;
+        fullres[i-1] = idInit(IDELEMS(res[i]),j);
+        ri1 = totake[i-1]->m;
+        for (j=IDELEMS(res[i])-1;j>=0;j--)
+        {
+          p = res[i]->m[j];
+          q = NULL;
+          while (p!=NULL)
+          {
+            if (toCopy)
+            {
+              if (origR!=NULL)
+                tq = prHeadR(p,origR);
+              else
+                tq = pHead(p);
+              pIter(p);
+            }
+            else
+            {
+              res[i]->m[j] = NULL;
+              if (origR!=NULL)
+              {
+                poly pp=p;
+                pIter(p);
+                pNext(pp)=NULL;
+                tq = prMoveR(pp, origR);
+              }
+              else
+              {
+                tq = p;
+                pIter(p);
+                pNext(tq) = NULL;
+              }
+            }
+//            pWrite(tq);
+            pTest(tq);
+            for (l=pVariables;l>0;l--)
+            {
+              if (origR!=NULL)
+                pSubExp(tq,l, p_GetExp(ri1[pGetComp(tq)-1],l,origR));
+              else
+                pSubExp(tq,l, pGetExp(ri1[pGetComp(tq)-1],l));
+            }
+            pSetm(tq);
+            pTest(tq);
+            q = pAdd(q,tq);
+            pTest(q);
+          }
+          fullres[i-1]->m[j] = q;
+        }
+      }
+      else
+      {
+        if (origR!=NULL)
+        {
+          fullres[i-1] = idInit(IDELEMS(res[i]),res[i]->rank);
+          for (j=IDELEMS(res[i])-1;j>=0;j--)
+          {
+            if (toCopy)
+              fullres[i-1]->m[j] = prCopyR(res[i]->m[j], origR);
+            else
+            {
+              fullres[i-1]->m[j] = prMoveR(res[i]->m[j], origR);
+              res[i]->m[j] = NULL;
+            }
+          }
+        }
+        else
+        {
+          if (toCopy)
+            fullres[i-1] = idCopy(res[i]);
+          else
+          {
+            fullres[i-1] = res[i];
+            res[i] = NULL;
+          }
+        }
+        for (j=IDELEMS(fullres[i-1])-1;j>=0;j--)
+          fullres[i-1]->m[j] = pSortCompCorrect(fullres[i-1]->m[j]);
+      }
+      if (!toCopy)
+      {
+        if (res[i]!=NULL) idDelete(&res[i]);
+      }
+    }
+  }
+  if (!toCopy)
+    omFreeSize((ADDRESS)res,(length+1)*sizeof(ideal));
+  //syzstr->length = length;
+  return fullres;
+}
+
+/*2
+* deleting all monomials the component of which correspond
+* to non-minimal generators
+*/
+static poly syStripOut(poly p,intvec * toStrip)
+{
+  if (toStrip==NULL) return p;
+  poly pp=p;
+
+  while ((pp!=NULL) && ((*toStrip)[pGetComp(pp)]!=0))
+    pDeleteLm(&pp);
+  p = pp;
+  if (pp!=NULL)
+  {
+    while (pNext(pp)!=NULL)
+    {
+      if ((*toStrip)[pGetComp(pNext(pp))]!=0)
+        pDeleteLm(&pNext(pp));
+      else
+        pIter(pp);
+    }
+  }
+  return p;
+}
+
+/*2
+* copies only those monomials the component of which correspond
+* to minimal generators
+*/
+static poly syStripOutCopy(poly p,intvec * toStrip)
+{
+  if (toStrip==NULL) return pCopy(p);
+  poly result=NULL,pp;
+
+  while (p!=NULL)
+  {
+    if ((*toStrip)[pGetComp(p)]==0)
+    {
+      if (result==NULL)
+      {
+        result = pp = pHead(p);
+      }
+      else
+      {
+        pNext(pp) = pHead(p);
+        pIter(pp);
+      }
+    }
+    pIter(p);
+  }
+  return result;
+}
+
+/*2
+* minimizes toMin
+*/
+static poly syMinimizeP(int toMin,syStrategy syzstr,intvec * ordn,int index,
+                        intvec * toStrip)
+{
+  int ii=0,i,j,tc;
+  poly p,pp,q=NULL,tq,pisN;
+  SSet sPairs=syzstr->resPairs[index];
+  poly tempStripped=NULL;
+
+  //pp=pCopy(syzstr->res[index+1]->m[toMin]);
+  pp = syStripOutCopy(syzstr->res[index+1]->m[toMin],toStrip);
+  while ((ii<ordn->length()) && ((*ordn)[ii]!=-1) &&
+             (sPairs[(*ordn)[ii]].syzind!=toMin))
+  {
+    ii++;
+  }
+  while (ii>=0)
+  {
+    i = (*ordn)[ii];
+    if (sPairs[i].isNotMinimal!=NULL)
+    {
+      tempStripped =
+        syStripOutCopy(syzstr->res[index+1]->m[sPairs[i].syzind],toStrip);
+      pisN = sPairs[i].isNotMinimal;
+      tc = pGetComp(pisN);
+      p = pp;
+      while (p!=NULL)
+      {
+        if (pGetComp(p)==tc)
+        {
+          tq = pInit();
+          for(j=pVariables; j>0; j--)
+            pSetExp(tq,j, pGetExp(p,j)-pGetExp(pisN,j));
+          pSetComp(tq, 0);
+          pSetCoeff0(tq,nDiv(pGetCoeff(p),pGetCoeff(pisN)));
+          pGetCoeff(tq) = nNeg(pGetCoeff(tq));
+          pSetm(tq);
+          q = pAdd(q,pMult_mm(pCopy(tempStripped),tq));
+          pDelete(&tq);
+        }
+        pIter(p);
+      }
+      if (q!=NULL)
+      {
+        pp = pAdd(pp,q);
+        q = NULL;
+      }
+      pDelete(&tempStripped);
+    }
+    ii--;
+  }
+  return pp;
+}
+
+/*2
+* minimizes toMin
+*/
+static poly syMinimizeP1(int toMin,syStrategy syzstr,intvec * ordn,int index,
+                        intvec * toStrip)
+{
+  int ii=0,i,j,tc,lp,ltS=-1;
+  poly p,mp=NULL,pp,q=NULL,tq,pisN;
+  SSet sPairs=syzstr->resPairs[index];
+  poly tempStripped=NULL;
+
+  pp = syStripOutCopy(syzstr->res[index+1]->m[toMin],toStrip);
+  kBucketInit(syzstr->bucket,pp,-1);
+  while ((ii<ordn->length()) && ((*ordn)[ii]!=-1) &&
+             (sPairs[(*ordn)[ii]].syzind!=toMin))
+  {
+    ii++;
+  }
+  while (ii>=0)
+  {
+    i = (*ordn)[ii];
+    if (sPairs[i].isNotMinimal!=NULL)
+    {
+      tempStripped =
+        syStripOutCopy(syzstr->res[index+1]->m[sPairs[i].syzind],toStrip);
+      tc = pGetComp(sPairs[i].isNotMinimal);
+      //p = pTakeOutComp1(&tempStripped,tc);
+      int lu;
+      pTakeOutComp(&tempStripped,tc,&p,&lu);
+      kBucketTakeOutComp(syzstr->bucket,tc,&mp,&lp);
+      mp = pDivideM(mp,p);
+      while (mp!=NULL)
+      {
+        p = pNext(mp);
+        pNext(mp) = NULL;
+        ltS = -1;
+        kBucket_Minus_m_Mult_p(syzstr->bucket,mp,tempStripped,&ltS);
+        mp = p;
+      }
+      pDelete(&mp);
+      pDelete(&tempStripped);
+    }
+    ii--;
+  }
+  kBucketClear(syzstr->bucket,&pp,&lp);
+  return pp;
+}
+
+/*2
+* deletes empty components after minimization
+*/
+void syKillEmptyEntres(resolvente res,int length)
+{
+  int i,j,jj,k,rj;
+  intvec * changes;
+  poly p;
+  ideal ri;
+
+  for (i=0;i<length;i++)
+  {
+    ri = res[i];
+    if (ri!=NULL)
+    {
+      rj = IDELEMS(ri);
+      changes = new intvec(rj+1,1,-1);
+      while ((rj>0) && (ri->m[rj-1]==NULL)) rj--;
+      j = k = 0;
+      while (j+k<rj)
+      {
+        if (ri->m[j+k]!=NULL)
+        {
+          ri->m[j] = ri->m[j+k];
+          (*changes)[j+k+1] = j+1;
+          j++;
+        }
+        else
+        {
+          k++;
+        }
+      }
+      for (jj=j;jj<rj;jj++)
+        ri->m[jj] = NULL;
+      if (res[i+1]!=NULL)
+      {
+        ri = res[i+1];
+        for (j=IDELEMS(ri)-1;j>=0;j--)
+        {
+          p = ri->m[j];
+          while (p!=NULL)
+          {
+            pSetComp(p,(*changes)[pGetComp(p)]);
+            pSetm(p);
+            pIter(p);
+          }
+        }
+      }
+      delete changes;
+    }
+  }
+}
+
+/*2
+* determines the components for minimization
+*/
+static intvec * syToStrip(syStrategy syzstr, int index)
+{
+  intvec * result=NULL;
+
+  if ((syzstr->resPairs[index-1]!=NULL) && (!idIs0(syzstr->res[index])))
+  {
+    result=new intvec(IDELEMS(syzstr->res[index])+1);
+    for (int i=(*syzstr->Tl)[index-1]-1;i>=0;i--)
+    {
+      if (syzstr->resPairs[index-1][i].isNotMinimal!=NULL)
+      {
+        (*result)[syzstr->resPairs[index-1][i].syzind+1] = 1;
+      }
+    }
+  }
+  return result;
+}
+
+/*2
+* re-computes the order of pairs during the algorithm
+* this ensures to procede with a triangular matrix
+*/
+static intvec * syOrdPairs(SSet sPairs, int length)
+{
+  intvec * result=new intvec(length,1,-1);
+  int i,j=0,k=-1,l,ii;
+
+  loop
+  {
+    l = -1;
+    for(i=0;i<length;i++)
+    {
+      if (sPairs[i].syzind>k)
+      {
+        if (l==-1)
+        {
+          l = sPairs[i].syzind;
+          ii = i;
+        }
+        else
+        {
+          if (sPairs[i].syzind<l)
+          {
+            l = sPairs[i].syzind;
+            ii = i;
+          }
+        }
+      }
+    }
+    if (l==-1) break;
+    (*result)[j] = ii;
+    j++;
+    k = l;
+  }
+  return result;
+}
+
+/*2
+* minimizes the output of LaScala
+*/
+static resolvente syReadOutMinimalRes(syStrategy syzstr,
+           BOOLEAN computeStd=FALSE)
+{
+  intvec * Strip, * ordn;
+  resolvente tres=(resolvente)omAlloc0((syzstr->length+1)*sizeof(ideal));
+  ring tmpR = NULL;
+  ring origR = currRing;
+
+//Print("Hier ");
+  if (computeStd)
+  {
+    tres[0] = syzstr->res[1];
+    syzstr->res[1] = idInit(IDELEMS(tres[0]),tres[0]->rank);
+    return tres;
+  }
+  int i,j,l,index,ii,i1;
+  poly p;
+  ideal rs;
+  SSet sPairs;
+  int * ord,*b0,*b1;
+
+  assume(syzstr->syRing != NULL);
+  rChangeCurrRing(syzstr->syRing);
+//Print("laeufts ");
+  syzstr->bucket = kBucketCreate();
+  for (index=syzstr->length-1;index>0;index--)
+  {
+    if (syzstr->resPairs[index]!=NULL)
+    {
+//Print("ideal %d: \n",index);
+      currcomponents = syzstr->truecomponents[index];
+      currShiftedComponents = syzstr->ShiftedComponents[index];
+      rChangeSComps(currcomponents, currShiftedComponents,
+                    IDELEMS(syzstr->res[index]));
+      sPairs = syzstr->resPairs[index];
+      Strip = syToStrip(syzstr,index);
+      tres[index+1] = idInit(IDELEMS(syzstr->res[index+1]),syzstr->res[index+1]->rank);
+      i1 = (*syzstr->Tl)[index];
+//Print("i1= %d\n",i1);
+      ordn = syOrdPairs(sPairs,i1);
+      for (i=0;i<i1;i++)
+      {
+        if ((sPairs[i].isNotMinimal==NULL) && (sPairs[i].lcm!=NULL))
+        {
+          l = sPairs[i].syzind;
+//Print("Minimiere Poly %d: ",l);pWrite(syzstr->res[index+1]->m[l]);
+          tres[index+1]->m[l] =
+            syMinimizeP1(l,syzstr,ordn,index,Strip);
+        }
+      }
+      delete Strip;
+      Strip = NULL;
+    }
+  }
+  currcomponents = syzstr->truecomponents[0];
+  currShiftedComponents = syzstr->ShiftedComponents[0];
+  rChangeSComps( currcomponents, currShiftedComponents,
+                 IDELEMS(syzstr->res[0]));
+  tres[1] = idInit(IDELEMS(syzstr->res[1]),syzstr->res[1]->rank);
+  sPairs = syzstr->resPairs[0];
+  for (i=(*syzstr->Tl)[0]-1;i>=0;i--)
+  {
+    if (sPairs[i].syzind>=0)
+    {
+      tres[1]->m[sPairs[i].syzind] = pCopy(syzstr->res[1]->m[sPairs[i].syzind]);
+    }
+  }
+/*--- changes to the original ring------------------*/
+  kBucketDestroy(&syzstr->bucket);
+  if (syzstr->syRing != NULL)
+  {
+    rChangeCurrRing(origR);
+    // Thomas: now make sure that all data which you need is pFetchCopied
+    // maybe incoporate it into syReorder ??
+  }
+  tres = syReorder(tres,syzstr->length,syzstr,FALSE,syzstr->res);
+  syKillEmptyEntres(tres,syzstr->length);
+  idSkipZeroes(tres[0]);
+  return tres;
+}
+
+/*3
+* minimizes any kind of resolution
+*/
+syStrategy syMinimize(syStrategy syzstr)
+{
+  if (syzstr->minres==NULL)
+  {
+    if (syzstr->resPairs!=NULL)
+    {
+      if (syzstr->hilb_coeffs==NULL)
+      {
+        syzstr->minres = syReadOutMinimalRes(syzstr);
+      }
+      else
+      {
+        syzstr->minres = syReorder(syzstr->orderedRes,syzstr->length,syzstr);
+      }
+    }
+    else if (syzstr->fullres!=NULL)
+    {
+      syMinimizeResolvente(syzstr->fullres,syzstr->length,1);
+      syzstr->minres = syzstr->fullres;
+      syzstr->fullres = NULL;
+    }
+  }
+  (syzstr->references)++;
+  return syzstr;
+}
+
+/*2
+* implementation of LaScala's algorithm
+* assumes that the given module is homogeneous
+* works with slanted degree, uses syChosePairs
+*/
+syStrategy syLaScala3(ideal arg,int * length)
+{
+  BOOLEAN noPair=FALSE;
+  int i,j,actdeg=32000,index=0,reg=-1;
+  int startdeg,howmuch;
+  poly p;
+  ideal temp;
+  SSet nextPairs;
+  syStrategy syzstr=(syStrategy)omAlloc0(sizeof(ssyStrategy));
+  ring origR = currRing;
+
+  if ((idIs0(arg)) ||
+      ((idRankFreeModule(arg)>0) && (!idHomModule(arg,NULL,&(syzstr->cw)))))
+  {
+    syzstr->minres = (resolvente)omAlloc0Bin(ideal_bin);
+    syzstr->length = 1;
+    syzstr->minres[0] = idInit(1,arg->rank);
+    return syzstr;
+  }
+
+  //crit = 0;
+  //euler = -1;
+  redpol = pInit();
+  syzstr->length = *length = pVariables+2;
+
+  // Creare dp,S ring and change to it
+  syzstr->syRing = rCurrRingAssure_dp_S();
+  assume(syzstr->syRing != origR);
+
+  // set initial ShiftedComps
+  currcomponents = (int*)omAlloc0((arg->rank+1)*sizeof(int));
+  currShiftedComponents = (long*)omAlloc0((arg->rank+1)*sizeof(long));
+  for (i=0;i<=arg->rank;i++)
+  {
+    currShiftedComponents[i] = (i)*SYZ_SHIFT_BASE;
+    currcomponents[i] = i;
+  }
+  rChangeSComps(currcomponents, currShiftedComponents, arg->rank);
+/*--- initializes the data structures---------------*/
+  syzstr->Tl = new intvec(*length);
+  temp = idInit(IDELEMS(arg),arg->rank);
+  for (i=0;i<IDELEMS(arg);i++)
+  {
+    temp->m[i] = prCopyR( arg->m[i], origR);
+    if (temp->m[i]!=NULL)
+    {
+      j = pTotaldegree(temp->m[i]);
+      if (j<actdeg) actdeg = j;
+    }
+  }
+  idTest(temp);
+  idSkipZeroes(temp);
+  idTest(temp);
+  syzstr->resPairs = syInitRes(temp,length,syzstr->Tl,syzstr->cw);
+  omFreeSize((ADDRESS)currcomponents,(arg->rank+1)*sizeof(int));
+  omFreeSize((ADDRESS)currShiftedComponents,(arg->rank+1)*sizeof(long));
+  syzstr->res = (resolvente)omAlloc0((*length+1)*sizeof(ideal));
+  syzstr->orderedRes = (resolvente)omAlloc0((*length+1)*sizeof(ideal));
+  syzstr->elemLength = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->truecomponents = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->ShiftedComponents = (long**)omAlloc0((*length+1)*sizeof(long*));
+  syzstr->backcomponents = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->Howmuch = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->Firstelem = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->sev = (unsigned long **) omAlloc0((*length+1)*sizeof(unsigned long *));
+  syzstr->bucket = kBucketCreate();
+  int len0=idRankFreeModule(temp)+1;
+
+  startdeg = actdeg;
+  nextPairs = syChosePairs(syzstr,&index,&howmuch,&actdeg);
+  //if (TEST_OPT_PROT) Print("(%d,%d)",howmuch,index);
+/*--- computes the resolution ----------------------*/
+  while (nextPairs!=NULL)
+  {
+    if (TEST_OPT_PROT) Print("%d",actdeg);
+    if (TEST_OPT_PROT) Print("(m%d)",index);
+    if (index==0)
+      i = syInitSyzMod(syzstr,index,len0);
+    else
+      i = syInitSyzMod(syzstr,index);
+    currcomponents = syzstr->truecomponents[si_max(index-1,0)];
+    currShiftedComponents = syzstr->ShiftedComponents[si_max(index-1,0)];
+    rChangeSComps(currcomponents, currShiftedComponents,
+                  IDELEMS(syzstr->res[si_max(index-1,0)]));
+    j = syInitSyzMod(syzstr,index+1);
+    if (index>0)
+    {
+      syRedNextPairs(nextPairs,syzstr,howmuch,index);
+      syCompactifyPairSet(syzstr->resPairs[index],(*syzstr->Tl)[index],0);
+    }
+    else
+      syRedGenerOfCurrDeg(syzstr,actdeg,index+1);
+/*--- creates new pairs -----------------------------*/
+    syCreateNewPairs(syzstr,index,i);
+    if (index<(*length)-1)
+    {
+      syCreateNewPairs(syzstr,index+1,j);
+    }
+    index++;
+    nextPairs = syChosePairs(syzstr,&index,&howmuch,&actdeg);
+    //if (TEST_OPT_PROT) Print("(%d,%d)",howmuch,index);
+  }
+  if (temp!=NULL) idDelete(&temp);
+  kBucketDestroy(&(syzstr->bucket));
+  if (origR != syzstr->syRing)
+    rChangeCurrRing(origR);
+  pDeleteLm(&redpol);
+  if (TEST_OPT_PROT) PrintLn();
+  return syzstr;
+}
+
Index: kernel/syz2.cc
===================================================================
--- kernel/syz2.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/syz2.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1087 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: syz2.cc,v 1.1.1.1 2003-10-06 12:16:04 Singular Exp $ */
+/*
+* ABSTRACT: resolutions
+*/
+
+#include "mod2.h"
+#include <mylimits.h>
+#include "structs.h"
+#include "omalloc.h"
+#include "syz.h"
+#include "polys.h"
+#include "febase.h"
+#include "kstd1.h"
+#include "kutil.h"
+#include "stairc.h"
+//#include "cntrlc.h"
+#include "intvec.h"
+#include "numbers.h"
+#include "modulop.h"
+#include "ideals.h"
+#include "intvec.h"
+#include "ring.h"
+#include "kbuckets.h"
+#include "prCopy.h"
+
+//#define SHOW_PROT
+//#define SHOW_RED
+//#define SHOW_HILB
+//#define SHOW_RESULT
+//#define INVERT_PAIRS
+//#define SHOW_CRIT
+//#define SHOW_SPRFL
+#define USE_CHAINCRIT
+#define poly_write(p) wrp(p);PrintLn()
+/*--- some heuristics to optimize the pair sets---*/
+/*--- chose only one (!!!) at the same time ------*/
+//#define USE_HEURISTIC1
+#define USE_HEURISTIC2
+
+#ifdef SHOW_CRIT
+static int crit;
+static int crit1;
+static int spfl;
+static int cons_pairs;
+static int crit_fails;
+#endif
+typedef struct sopen_pairs open_pairs;
+typedef open_pairs* crit_pairs;
+struct sopen_pairs
+{
+  crit_pairs next;
+  int first_poly;
+  int second_poly;
+};
+/*3
+* computes pairs from the new elements (beginning with the element newEl)
+* in the module index
+*/
+static void syCreateNewPairs_Hilb(syStrategy syzstr, int index,
+            int actdeg)
+{
+  SSet temp;
+  SObject tso;
+  poly toHandle,tsyz=NULL,p,pp;
+  int r1,r2=0,rr,l=(*syzstr->Tl)[index];
+  int i,j,r=0,ti;
+  BOOLEAN toComp=FALSE;
+#ifdef USE_CHAINCRIT
+  crit_pairs cp=NULL,tcp;
+#endif
+  actdeg += index;
+  long * ShiftedComponents = syzstr->ShiftedComponents[index-1];
+  int* Components = syzstr->truecomponents[index-1];
+
+  while ((l>0) && ((syzstr->resPairs[index])[l-1].lcm==NULL)) l--;
+  rr = l-1;
+  while ((rr>=0) && (((syzstr->resPairs[index])[rr].p==NULL) || 
+        ((syzstr->resPairs[index])[rr].order>actdeg))) rr--;
+  r2 = rr+1; 
+  while ((rr>=0) && ((syzstr->resPairs[index])[rr].order==actdeg)
+         && ((syzstr->resPairs[index])[rr].syzind<0))
+  {
+    rr--;
+    r++;
+  }
+  if (r==0) return;
+  ideal nP=idInit(l,syzstr->res[index]->rank);
+#ifdef INVERT_PAIRS
+  r1 = rr+1;
+#else
+  r1 = r2-1;
+#endif
+/*---------- there are new pairs ------------------------------*/
+  loop
+  {
+/*--- chose first new elements --------------------------------*/
+    toComp = FALSE;
+    toHandle = (syzstr->resPairs[index])[r1].p;
+    if (toHandle!=NULL)
+    {
+      int tc=pGetComp(toHandle);
+      (syzstr->resPairs[index])[r1].syzind = 0;
+      for (i=0; i<r1;i++)
+      {
+        if (((syzstr->resPairs[index])[i].p!=NULL) &&
+            (pGetComp((syzstr->resPairs[index])[i].p)==tc))
+        {
+#ifdef USE_CHAINCRIT
+          tcp = cp;
+          if (tcp!=NULL)
+          {
+            while ((tcp!=NULL) && 
+              ((tcp->first_poly!=i)||(tcp->second_poly!=r1))) tcp = tcp->next;
+          }
+          if (tcp==NULL)
+          {
+#endif
+            p = pOne();
+            pLcm((syzstr->resPairs[index])[i].p,toHandle,p);
+            pSetm(p);
+            j = 0;
+            while (j<i)
+            { 
+              if (nP->m[j]!=NULL)
+              {
+                if (pLmDivisibleByNoComp(nP->m[j],p))
+                {
+                  pDelete(&p);
+                  p = NULL;
+                  break;
+                }
+                else if (pLmDivisibleByNoComp(p,nP->m[j]))
+                {
+                  pDelete(&(nP->m[j]));
+                  nP->m[j] = NULL;
+                }
+#ifdef USE_CHAINCRIT
+                else
+                {
+                  poly p1,p2;
+                  int ip=pVariables;
+                  p1 = pDivide(p,(syzstr->resPairs[index])[i].p);
+                  p2 = pDivide(nP->m[j],(syzstr->resPairs[index])[j].p);
+                  while ((ip>0) && (pGetExp(p1,ip)*pGetExp(p2,ip)==0)) ip--;
+                  if (ip==0)
+                  {
+#ifdef SHOW_SPRFL
+Print("Hier: %d, %d\n",j,i);
+#endif
+                    if (i>rr)
+                    {
+                      tcp=(crit_pairs)omAlloc0(sizeof(sopen_pairs));
+                      tcp->next = cp;
+                      tcp->first_poly = j;
+                      tcp->second_poly = i;
+                      cp = tcp;
+                      tcp = NULL;
+                    }
+                    else
+                    {
+                      ti=0;
+                      while ((ti<l) && (((syzstr->resPairs[index])[ti].ind1!=j)||
+                             ((syzstr->resPairs[index])[ti].ind2!=i))) ti++;
+                      if (ti<l) 
+                      {
+#ifdef SHOW_SPRFL
+Print("gefunden in Mod %d: ",index); poly_write((syzstr->resPairs[index])[ti].lcm);
+#endif
+                        syDeletePair(&(syzstr->resPairs[index])[ti]);
+#ifdef SHOW_CRIT
+                        crit1++;
+#endif
+                        toComp = TRUE;
+                      }
+                    }
+                  }
+                  pDelete(&p1);
+                  pDelete(&p2);
+                }
+#endif
+              }
+              j++;
+            }
+            if (p!=NULL)
+            {
+              nP->m[i] = p;
+            }
+#ifdef USE_CHAINCRIT
+          }
+          else
+          {
+#ifdef SHOW_CRIT
+            crit1++;
+#endif
+          }
+#endif
+        }
+      }
+      if (toComp) syCompactify1(syzstr->resPairs[index],&l,r1);
+      for (i=0;i<r1;i++)
+      {
+        if (nP->m[i]!=NULL)
+        {
+          tso.lcm = p = nP->m[i];
+          nP->m[i] = NULL;
+          tso.order = pTotaldegree(p);
+          if ((syzstr->cw!=NULL) && (index>0) && (pGetComp(p)>0))
+          {
+            int ii=index-1,jj=pGetComp(p);
+            while (ii>0)
+            {
+              jj = pGetComp(syzstr->res[ii]->m[jj-1]);
+              ii--;
+            }
+            tso.order += (*syzstr->cw)[jj-1];
+          }
+          tso.p1 = (syzstr->resPairs[index])[i].p;
+          tso.p2 = toHandle;
+          tso.ind1 = i;
+          tso.ind2 = r1;
+          tso.syzind = -1;
+          tso.isNotMinimal = (poly)1;
+          tso.p = NULL;
+          tso.length = -1;
+          number coefgcd =
+            nGcd(pGetCoeff(tso.p1),pGetCoeff(tso.p2),currRing);
+          tso.syz = pCopy((syzstr->resPairs[index])[i].syz);
+          poly tt = pDivide(tso.lcm,tso.p1);
+          pSetCoeff(tt,nDiv(pGetCoeff(tso.p1),coefgcd));
+          tso.syz = pMult_mm(tso.syz,tt);
+          pDelete(&tt);
+          coefgcd = nNeg(coefgcd);
+          pp = pCopy((syzstr->resPairs[index])[r1].syz);
+          tt = pDivide(tso.lcm,tso.p2);
+          pSetCoeff(tt,nDiv(pGetCoeff(tso.p2),coefgcd));
+          pp = pMult_mm(pp,tt);
+          pDelete(&tt);
+          tso.syz = pAdd(pp,tso.syz);
+          nDelete(&coefgcd);
+          pSetComp(tso.lcm,pGetComp((syzstr->resPairs[index])[r1].syz));
+#ifdef SHOW_PROT
+Print("erzeuge Paar im Modul %d,%d mit: \n",index,tso.order);
+PrintS("poly1: ");poly_write(tso.p1);
+PrintS("poly2: ");poly_write(tso.p2);
+PrintS("syz: ");poly_write(tso.syz);
+PrintS("sPoly: ");poly_write(tso.p);
+PrintLn();
+#endif
+          syEnterPair(syzstr,&tso,&l,index);
+        }
+      }
+    }
+#ifdef INVERT_PAIRS
+    r1++;
+    if (r1>=r2) break;
+#else
+    r1--;
+    if (r1<=rr) break;
+#endif
+  }
+  idDelete(&nP);
+#ifdef USE_CHAINCRIT
+  while (cp!=NULL)
+  {
+    tcp = cp;
+    cp = cp->next;
+    omFreeSize((ADDRESS)tcp,sizeof(sopen_pairs));
+  }
+#endif
+}
+
+/*3
+* determines the place of a polynomial in the right ordered resolution
+* set the vectors of truecomponents
+*/
+static void syOrder_Hilb(poly p,syStrategy syzstr,int index)
+{
+  int i=IDELEMS(syzstr->orderedRes[index]);
+
+  while ((i>0) && (syzstr->orderedRes[index]->m[i-1]==NULL)) i--;
+  syzstr->orderedRes[index]->m[i] = p;
+}
+
+static void syHalfPair(poly syz, int newEl, syStrategy syzstr, int index)
+{
+  SObject tso;
+  memset(&tso,0,sizeof(tso));
+  int l=(*syzstr->Tl)[index];
+
+  while ((l>0) && ((syzstr->resPairs[index])[l-1].syz==NULL)) l--;
+  if ((syzstr->cw!=NULL) && (index>0) && (pGetComp(syz)>0))
+  {
+    int ii=index-1,jj=pGetComp(syz);
+    while (ii>0)
+    {
+      jj = pGetComp(syzstr->res[ii]->m[jj-1]);
+      ii--;
+    }
+    tso.order += (*syzstr->cw)[jj-1];
+  }
+  tso.p1 = NULL;
+  tso.p2 = NULL;
+  tso.ind1 = 0;
+  tso.ind2 = 0;
+  tso.syzind = -1;
+  tso.isNotMinimal = NULL;
+  tso.p = syz;
+  tso.order = pTotaldegree(syz);
+  tso.syz = pHead(syz);
+  pSetComp(tso.syz,newEl+1);
+  pSetm(tso.syz);
+  tso.lcm = pHead(tso.syz);
+  tso.length = pLength(syz);
+  syOrder_Hilb(syz,syzstr,index);
+#ifdef SHOW_PROT
+Print("erzeuge Halbpaar im Module %d,%d mit: \n",index,tso.order);
+PrintS("syz: ");poly_write(tso.syz);
+PrintS("sPoly: ");poly_write(tso.p);
+PrintLn();
+#endif
+  syEnterPair(syzstr,&tso,&l,index);
+}
+/*3
+* computes the order of pairs of same degree
+* must be monoton
+*/
+static intvec* syLinStrat2(SSet nextPairs, syStrategy syzstr,
+                          int howmuch, int index,intvec ** secondpairs)
+{
+  ideal o_r=syzstr->res[index+1];
+  int i=0,i1=0,i2=0,l,ll=IDELEMS(o_r);
+  intvec *result=new intvec(howmuch+1);
+  BOOLEAN isDivisible;
+  SObject tso;
+
+#ifndef USE_HEURISTIC2
+  while (i1<howmuch)
+  {
+    (*result)[i1] = i1+1;
+    i1++;
+  }
+  return result;
+#else
+  while ((ll>0) && (o_r->m[ll-1]==NULL)) ll--;
+  while (i<howmuch)
+  {
+    tso = nextPairs[i];
+    isDivisible = FALSE;
+    l = 0;
+    while ((l<ll) && (!isDivisible))
+    {
+      if (o_r->m[l]!=NULL)
+      {
+        isDivisible = isDivisible ||
+          pLmDivisibleBy(o_r->m[l],tso.lcm);
+      }
+      l++;
+    }
+    if (isDivisible)
+    {
+#ifdef SHOW_PROT
+Print("streiche Paar im Modul %d,%d mit: \n",index,nextPairs[i].order);
+PrintS("poly1: ");poly_write(nextPairs[i].p1);
+PrintS("poly2: ");poly_write(nextPairs[i].p2);
+PrintS("syz: ");poly_write(nextPairs[i].syz);
+PrintS("sPoly: ");poly_write(nextPairs[i].p);
+PrintLn();
+#endif
+      //syDeletePair(&nextPairs[i]);
+      if (*secondpairs==NULL) *secondpairs = new intvec(howmuch);
+      (**secondpairs)[i2] = i+1;
+      i2++;
+#ifdef SHOW_CRIT
+      crit++;
+#endif
+    }
+    else
+    {
+//      nextPairs[i].p = sySPoly(tso.p1, tso.p2,tso.lcm);
+      (*result)[i1] = i+1;
+      i1++;
+    }
+    i++;
+  }
+  return result;
+#endif
+}
+
+inline void sySPRedSyz(syStrategy syzstr,sSObject redWith,poly q=NULL)
+{
+  poly p=pDivide(q,redWith.p);
+  pSetCoeff(p,nDiv(pGetCoeff(q),pGetCoeff(redWith.p)));
+  int il=-1;
+  kBucket_Minus_m_Mult_p(syzstr->syz_bucket,p,redWith.syz,&il,NULL);
+  pDelete(&p);
+}
+
+static poly syRed_Hilb(poly toRed,syStrategy syzstr,int index)
+{
+  ideal redWith=syzstr->res[index];
+  if (redWith==NULL) return toRed;
+  int j=IDELEMS(redWith),i;
+  poly q,result=NULL,resultp;
+
+  while ((j>0) && (redWith->m[j-1]==NULL)) j--;
+  if ((toRed==NULL) || (j==0)) return toRed;
+  kBucketInit(syzstr->bucket,toRed,-1);
+  q = kBucketGetLm(syzstr->bucket);
+  loop
+  {
+    if (q==NULL)
+    {
+      break;
+    }
+    i = 0;
+    loop
+    {
+      if (pLmDivisibleBy(redWith->m[i],q))
+      {
+        number up = kBucketPolyRed(syzstr->bucket,redWith->m[i],
+                         pLength(redWith->m[i]), NULL);
+        nDelete(&up);
+        q = kBucketGetLm(syzstr->bucket);
+        if (toRed==NULL) break;
+        i = 0;
+      }
+      else
+      {
+        i++;
+      }
+      if ((i>=j) || (q==NULL)) break;
+    }
+    if (q!=NULL)
+    {
+      if (result==NULL)
+      {
+        resultp = result = kBucketExtractLm(syzstr->bucket);
+      }
+      else
+      {
+        pNext(resultp) = kBucketExtractLm(syzstr->bucket);
+        pIter(resultp);
+      }
+      q = kBucketGetLm(syzstr->bucket);
+    }
+  }
+  kBucketClear(syzstr->bucket,&q,&i);
+  if (q!=NULL) PrintS("Hier ist was schief gelaufen!\n");
+  return result;
+}
+
+intvec *ivStrip(intvec* arg)
+{
+  int l=arg->rows()*arg->cols(),i=0,ii=0;
+  intvec *tempV=new intvec(l);
+
+  while (i+ii<l)
+  {
+    if ((*arg)[i+ii]==0)
+    {
+      ii++;
+    }
+    else
+    {
+      (*tempV)[i] = (*arg)[i+ii];
+      i++;
+    }
+  }
+  if (i==0)
+  {
+    delete tempV;
+    return NULL;
+  }
+  intvec * result=new intvec(i+1);
+  for (ii=0;ii<i;ii++)
+   (*result)[ii] = (*tempV)[ii];
+  delete tempV;
+  return result;
+}
+
+/*3
+* reduces all pairs of degree deg in the module index
+* put the reduced generators to the resolvente which contains
+* the truncated kStd
+*/
+static void syRedNextPairs_Hilb(SSet nextPairs, syStrategy syzstr,
+               int howmuch, int index,int actord,int* toSub,
+               int *maxindex,int *maxdeg)
+{
+  int i,j,k=IDELEMS(syzstr->res[index]);
+  int ks=IDELEMS(syzstr->res[index+1]),kk,l,ll;
+  int ks1=IDELEMS(syzstr->orderedRes[index+1]);
+  int kres=(*syzstr->Tl)[index];
+  int toGo=0;
+  int il;
+  number coefgcd,n;
+  SSet redset=syzstr->resPairs[index];
+  poly p=NULL,q,tp;
+  intvec *spl1;
+  SObject tso;
+  intvec *spl3=NULL;
+#ifdef USE_HEURISTIC1
+  intvec *spl2=new intvec(howmuch+1,howmuch+1,0);
+  int there_are_superfluous=0;
+  int step=1,jj,j1,j2;
+#endif
+  long * ShiftedComponents = syzstr->ShiftedComponents[index];
+  int* Components = syzstr->truecomponents[index];
+  assume(Components != NULL && ShiftedComponents != NULL);
+  BOOLEAN need_reset;
+
+  actord += index;
+  if ((nextPairs==NULL) || (howmuch==0)) return;
+  while ((k>0) && (syzstr->res[index]->m[k-1]==NULL)) k--;
+  while ((ks>0) && (syzstr->res[index+1]->m[ks-1]==NULL)) ks--;
+  while ((ks1>0) && (syzstr->orderedRes[index+1]->m[ks1-1]==NULL)) ks1--;
+  while ((kres>0) &&
+        ((redset[kres-1].p==NULL) || (redset[kres-1].order>actord))) kres--;
+  while ((kres<(*syzstr->Tl)[index]) &&
+         (redset[kres-1].order!=0) && (redset[kres-1].order<=actord)) kres++;
+  spl1 = syLinStrat2(nextPairs,syzstr,howmuch,index,&spl3);
+#ifdef SHOW_PROT
+PrintS("spl1 ist hier: ");spl1->show(0,0);
+#endif
+  i=0;
+  kk = (*spl1)[i]-1;
+  if (index==1)
+  {
+    intvec * temp1_hilb = hHstdSeries(syzstr->res[index],NULL,NULL,NULL);
+    if (actord<temp1_hilb->length())
+    {
+      toGo = (*temp1_hilb)[actord];
+#ifdef SHOW_HILB
+Print("\nStze toGo im Modul %d und Grad %d auf: %d\n",1,actord-1,toGo);
+#endif
+    }
+    delete temp1_hilb;
+  }
+  else
+  {
+    if (actord<=(syzstr->hilb_coeffs[index])->length())
+    {
+      toGo = (*syzstr->hilb_coeffs[index])[actord-1];
+#ifdef SHOW_HILB
+Print("\nStze toGo im Modul %d und Grad %d auf: %d\n",index,actord-1,toGo);
+#endif
+    }
+  }
+  if ((syzstr->hilb_coeffs[index+1]!=NULL) &&
+      (actord<=(syzstr->hilb_coeffs[index+1])->length()))
+  {
+    toGo += (*syzstr->hilb_coeffs[index+1])[actord-1];
+#ifdef SHOW_HILB
+Print("\nAddiere zu toGo aus Modul %d und Grad %d: %d\n",index+1,actord-1,(*syzstr->hilb_coeffs[index+1])[actord-1]);
+#endif
+  }
+#ifdef SHOW_HILB
+Print("<H%d>",toGo);
+#endif
+  while (kk>=0)
+  {
+    if (toGo==0) 
+    {
+      while (kk>=0)
+      {
+        pDelete(&nextPairs[kk].p);
+        pDelete(&nextPairs[kk].syz);
+        syDeletePair(&nextPairs[kk]);
+        nextPairs[kk].p = nextPairs[kk].syz = nextPairs[kk].lcm = NULL;
+        i++;
+        kk = (*spl1)[i]-1;
+#ifdef USE_HEURISTIC2
+        if (kk<0)
+        {
+          i = 0;
+          delete spl1;
+          spl1 = spl3;
+          spl3 = NULL;
+          if (spl1!=NULL)
+            kk = (*spl1)[i]-1;
+        }
+#endif
+      }
+      if (spl1!=NULL) delete spl1;
+      break;
+    }
+    tso = nextPairs[kk];
+    if ((tso.p1!=NULL) && (tso.p2!=NULL))
+    {
+#ifdef SHOW_CRIT
+      cons_pairs++;
+#endif
+      //tso.p = sySPoly(tso.p1, tso.p2,tso.lcm);
+      tso.p = ksOldCreateSpoly(tso.p2, tso.p1);
+#ifdef SHOW_PROT
+PrintS("reduziere Paar mit: \n");
+PrintS("poly1: ");poly_write(tso.p1);
+PrintS("poly2: ");poly_write(tso.p2);
+PrintS("syz: ");poly_write(tso.syz);
+PrintS("sPoly: ");poly_write(tso.p);
+#endif
+      if (tso.p != NULL)
+      {
+        kBucketInit(syzstr->bucket,tso.p,-1);
+        kBucketInit(syzstr->syz_bucket,tso.syz,-1);
+        q = kBucketGetLm(syzstr->bucket);
+        j = 0;
+        while (j<kres) 
+        {
+          if ((redset[j].p!=NULL) && (pLmDivisibleBy(redset[j].p,q)) 
+              && ((redset[j].ind1!=tso.ind1) || (redset[j].ind2!=tso.ind2)))
+          {
+#ifdef SHOW_RED
+kBucketClear(syzstr->bucket,&tso.p,&tso.length);
+kBucketClear(syzstr->syz_bucket,&tso.syz,&il);
+PrintS("reduziere: ");poly_write(tso.p);
+PrintS("syz: ");poly_write(tso.syz);
+PrintS("mit: ");poly_write(redset[j].p);
+PrintS("syz: ");poly_write(redset[j].syz);
+kBucketInit(syzstr->bucket,tso.p,tso.length);
+kBucketInit(syzstr->syz_bucket,tso.syz,il);
+#endif
+            sySPRedSyz(syzstr,redset[j],q);
+            number up = kBucketPolyRed(syzstr->bucket,redset[j].p,
+                         redset[j].length, NULL);
+            nDelete(&up);
+            q = kBucketGetLm(syzstr->bucket);
+#ifdef SHOW_RED
+kBucketClear(syzstr->bucket,&tso.p,&tso.length);
+kBucketClear(syzstr->syz_bucket,&tso.syz,&il);
+PrintS("zu: ");poly_write(tso.p);
+PrintS("syz: ");poly_write(tso.syz);
+kBucketInit(syzstr->bucket,tso.p,tso.length);
+kBucketInit(syzstr->syz_bucket,tso.syz,il);
+PrintLn();
+#endif
+            if (q==NULL) break;
+            j = 0;
+          }
+          else
+          {
+            j++;
+          }
+        }
+        kBucketClear(syzstr->bucket,&tso.p,&tso.length);
+        kBucketClear(syzstr->syz_bucket,&tso.syz,&il);
+      }
+#ifdef SHOW_PROT
+PrintS("erhalte Paar mit: \n");
+PrintS("syz: ");poly_write(tso.syz);
+PrintS("sPoly: ");poly_write(tso.p);
+PrintLn();
+#endif
+#ifdef SHOW_SPRFL
+//PrintLn();
+wrp(tso.lcm);
+Print(" mit index %d, %d ",tso.ind1,tso.ind2);
+#endif
+      if (tso.p != NULL)
+      {
+        if (TEST_OPT_PROT) PrintS("g");
+        (*toSub)++;
+        toGo--;
+        if (!nIsOne(pGetCoeff(tso.p)))
+        {
+          number n=nInvers(pGetCoeff(tso.p));
+          pNorm(tso.p);
+          pMult_nn(tso.syz,n);
+          nDelete(&n);
+        }
+        if (k==IDELEMS((syzstr->res)[index]))
+          syEnlargeFields(syzstr,index);
+        syzstr->res[index]->m[k] = tso.p;
+        k++;
+      }
+      else
+      {
+        if (ks==IDELEMS(syzstr->res[index+1]))
+          syEnlargeFields(syzstr,index+1);
+        syzstr->res[index+1]->m[ks] = syRed_Hilb(tso.syz,syzstr,index+1);
+        if (syzstr->res[index+1]->m[ks]!=NULL)
+        {
+          if (TEST_OPT_PROT) PrintS("s");
+          toGo--;
+          pNorm(syzstr->res[index+1]->m[ks]);
+          syHalfPair(syzstr->res[index+1]->m[ks],ks1,syzstr,index+1);
+          ks++;
+          ks1++;
+          if (index+1>*maxindex) *maxindex = index+1;
+          if (actord-index>*maxdeg) *maxdeg = actord-index;
+        }
+        else
+        {
+          if (TEST_OPT_PROT) PrintS("-");
+#ifdef SHOW_CRIT
+          spfl++;
+#endif
+#ifdef USE_HEURISTIC1
+          if (there_are_superfluous>=0)
+          {
+            j = i+1;
+            jj = (*spl1)[j]-1;
+            j1 = 1;
+            while (jj>=0)
+            {
+              if (tso.ind2==nextPairs[jj].ind2)
+              {
+                IMATELEM(*spl2,j1,step) = jj+1;
+                j1++;
+                for (j2=j;j2<spl1->length()-1;j2++)
+                {
+                  (*spl1)[j2] = (*spl1)[j2+1];
+                }
+              }
+              else
+              {
+                j++;
+              }
+              jj = (*spl1)[j]-1;
+            }
+            step++;
+            if (there_are_superfluous==0) there_are_superfluous = 1;
+          }
+#endif
+#ifdef SHOW_SPRFL
+Print("ist ueberfluessig in Mod %d",index);
+//Print("\n ueberfluessig in Mod %d:",index);
+//wrp(tso.lcm);
+//PrintLn();
+#endif
+        }
+        tso.syz = NULL;
+        syDeletePair(&tso);
+        tso.p = tso.syz = tso.lcm = NULL;
+      }
+      nextPairs[kk] = tso;
+    }
+#ifdef SHOW_SPRFL
+PrintLn();
+#endif
+    i++;
+#ifdef SHOW_PROT
+PrintS("spl1 ist hier: ");spl1->show(0,0);
+Print("naechstes i ist: %d",i);
+#endif
+    kk = (*spl1)[i]-1;
+#ifdef USE_HEURISTIC1
+    if ((kk<0) && (there_are_superfluous>0))
+    {
+      i = 0;
+      delete spl1;
+      spl1 = ivStrip(spl2); 
+      delete spl2;
+      if (spl1!=NULL)
+      {
+        there_are_superfluous = -1;
+        kk = (*spl1)[i]-1;
+      }
+    } 
+#endif
+#ifdef USE_HEURISTIC2
+    if ((kk<0) && (toGo>0))
+    {
+#ifdef SHOW_CRIT
+      crit_fails++;
+#endif
+      i = 0;
+      delete spl1;
+      spl1 = spl3;
+      spl3 = NULL;
+      if (spl1!=NULL)
+        kk = (*spl1)[i]-1;
+    }
+#endif
+  }
+  delete spl1;
+  if (spl3!=NULL) delete spl3;
+}
+
+void sySetNewHilb(syStrategy syzstr, int toSub,int index,int actord)
+{
+  int i;
+  actord += index;
+  intvec * temp_hilb = hHstdSeries(syzstr->res[index+1],NULL,NULL,NULL);
+  intvec * cont_hilb = hHstdSeries(syzstr->res[index],NULL,NULL,NULL);
+  if ((index+1<syzstr->length) && (syzstr->hilb_coeffs[index+1]==NULL))
+  {
+    syzstr->hilb_coeffs[index+1] = new intvec(16*((actord/16)+1));
+  }
+  else if (actord>=syzstr->hilb_coeffs[index+1]->length())
+  {
+    intvec * ttt=new intvec(16*((actord/16)+1));
+    for (i=syzstr->hilb_coeffs[index+1]->length()-1;i>=0;i--)
+    {
+      (*ttt)[i] = (*(syzstr->hilb_coeffs[index+1]))[i];
+    }
+    delete syzstr->hilb_coeffs[index+1];
+    syzstr->hilb_coeffs[index+1] = ttt;
+  }
+  if (actord+1<temp_hilb->length())
+  {
+#ifdef SHOW_HILB
+Print("\nSetze fuer Modul %d im Grad %d die Wert: \n",index+1,actord);
+(temp_hilb)->show(0,0);
+#endif
+    int k=si_min(temp_hilb->length()-1,(syzstr->hilb_coeffs[index+1])->length());
+    for (int j=k;j>actord;j--)
+      (*(syzstr->hilb_coeffs[index+1]))[j-1] = (*temp_hilb)[j];
+  }
+  else
+  {
+    (*(syzstr->hilb_coeffs[index+1]))[actord] = 0;
+  }
+  delete temp_hilb;
+  if ((index>1) && (actord<=syzstr->hilb_coeffs[index]->length()))
+  {
+#ifdef SHOW_HILB
+Print("\nSubtrahiere im Modul %d im Grad %d den Wert: %d\n",index,actord-1,toSub);
+#endif
+    (*syzstr->hilb_coeffs[index])[actord-1]-=toSub;
+  }
+  if (syzstr->hilb_coeffs[index]!=NULL)
+  {
+    if (cont_hilb->length()>syzstr->hilb_coeffs[index]->length())
+      syzstr->hilb_coeffs[index]->resize(cont_hilb->length());
+    for (int j=cont_hilb->length()-1;j>actord;j--)
+      (*(syzstr->hilb_coeffs[index]))[j-1] = (*cont_hilb)[j];
+  }
+  delete cont_hilb;
+#ifdef SHOW_HILB
+Print("<h,%d>",(*(syzstr->hilb_coeffs[index+1]))[actord]);
+#endif
+}
+
+/*3
+* reduces the generators of the module index in degree deg
+* (which are actual syzygies of the module index-1)
+* wrt. the ideal generated by elements of lower degrees
+*/
+static void syRedGenerOfCurrDeg_Hilb(syStrategy syzstr, int deg,int *maxindex,int *maxdeg)
+{
+  ideal res=syzstr->res[1];
+  int i=0,j,k=IDELEMS(res),k1=IDELEMS(syzstr->orderedRes[1]);
+  SSet sPairs1=syzstr->resPairs[1];
+  SSet sPairs=syzstr->resPairs[0];
+
+  while ((k>0) && (res->m[k-1]==NULL)) k--;
+  while ((k1>0) && (syzstr->orderedRes[1]->m[k1-1]==NULL)) k1--;
+  while ((i<(*syzstr->Tl)[0]) && (((sPairs)[i].syz==NULL) ||
+          ((sPairs)[i].order<deg)))
+    i++;
+  if ((i>=(*syzstr->Tl)[0]) || ((sPairs)[i].order>deg)) return;
+  while ((i<(*syzstr->Tl)[0]) && (((sPairs)[i].syz==NULL) ||
+         ((sPairs)[i].order==deg)))
+  {
+    if ((sPairs)[i].syz!=NULL)
+    {
+#ifdef SHOW_PROT
+PrintS("reduziere Erzeuger: \n");
+PrintS("syz: ");poly_write((sPairs)[i].syz);
+#endif
+      (sPairs)[i].syz = syRed_Hilb((sPairs)[i].syz,syzstr,1);
+#ifdef SHOW_PROT
+PrintS("erhalte Erzeuger: \n");
+PrintS("syz: ");poly_write((sPairs)[i].syz);
+PrintLn();
+#endif
+      if ((sPairs)[i].syz != NULL)
+      {
+        if (k==IDELEMS(res))
+        {
+          syEnlargeFields(syzstr,1);
+          res=syzstr->res[1];
+        }
+        if (TEST_OPT_DEBUG)
+        {
+          if ((sPairs)[i].isNotMinimal==NULL)
+          {
+            PrintS("\nminimal generator: ");
+            pWrite((syzstr->resPairs[0])[i].syz);
+            PrintS("comes from: ");pWrite((syzstr->resPairs[0])[i].p1);
+            PrintS("and: ");pWrite((syzstr->resPairs[0])[i].p2);
+          }
+        }
+        res->m[k] = (sPairs)[i].syz;
+        pNorm(res->m[k]);
+        syHalfPair(res->m[k],k1,syzstr,1);
+        k1++;
+        k++;
+        if (1>*maxindex) *maxindex = 1;
+        if (deg-1>*maxdeg) *maxdeg = deg-1;
+      }
+    }
+    i++;
+  }
+}
+
+/*3
+* reorders the result (stored in orderedRes) according
+* to the seqence given by res
+*/
+static void syReOrdResult_Hilb(syStrategy syzstr,int maxindex,int maxdeg)
+{
+  ideal reor,toreor;
+  int i,j,k,l,m,togo;
+  syzstr->betti = new intvec(maxdeg,maxindex+1,0);
+  (*syzstr->betti)[0] = 1;
+  for (i=1;i<=syzstr->length;i++)
+  {
+    if (!idIs0(syzstr->orderedRes[i])) 
+    {
+      toreor = syzstr->orderedRes[i];
+      k = IDELEMS(toreor);
+      while ((k>0) && (toreor->m[k-1]==NULL)) k--;
+      reor = idInit(k,toreor->rank);
+      togo = IDELEMS(syzstr->res[i]);
+      for (j=0;j<k;j++)
+      {
+        if (toreor->m[j]!=NULL) (IMATELEM(*syzstr->betti,pFDeg(toreor->m[j])-i+1,i+1))++;
+        reor->m[j] = toreor->m[j];
+        toreor->m[j] = NULL;
+      }
+      m = 0; 
+      for (j=0;j<togo;j++)
+      {
+        if (syzstr->res[i]->m[j]!=NULL)
+        {
+          l = 0;
+          while ((l<k) && (syzstr->res[i]->m[j]!=reor->m[l])) l++;
+          if (l<k)
+          {
+            toreor->m[m] = reor->m[l];
+            reor->m[l] = NULL;
+            m++;
+          }
+        }
+      }
+      idDelete(&reor);
+    }
+  }
+}
+
+/*2
+* the CoCoA-algorithm for free resolutions, using a formula 
+* for remaining pairs based on Hilbert-functions
+*/
+syStrategy syHilb(ideal arg,int * length)
+{
+  int i,j,actdeg=32000,index=0,reg=-1;
+  int startdeg,howmuch,toSub=0;
+  int maxindex=0,maxdeg=0;
+  ideal temp=NULL;
+  SSet nextPairs;
+  ring origR = currRing;
+  syStrategy syzstr=(syStrategy)omAlloc0(sizeof(ssyStrategy));
+
+  if ((idIs0(arg)) || (idRankFreeModule(arg)>0))
+  {
+    syzstr->minres = (resolvente)omAllocBin(sip_sideal_bin);
+    syzstr->length = 1;
+    syzstr->minres[0] = idInit(1,arg->rank);
+    return syzstr;
+  }
+  
+  // Creare dp,S ring and change to it
+  syzstr->syRing = rCurrRingAssure_dp_C();
+
+  // set initial ShiftedComps
+  currcomponents = (int*)omAlloc0((arg->rank+1)*sizeof(int));
+  currShiftedComponents = (long*)omAlloc0((arg->rank+1)*sizeof(long));
+
+/*--- initializes the data structures---------------*/
+#ifdef SHOW_CRIT
+  crit = 0;
+  crit1 = 0;
+  spfl = 0;
+  cons_pairs = 0;
+  crit_fails = 0;
+#endif
+  syzstr->length = *length = pVariables+2;
+  syzstr->Tl = new intvec(*length+1);
+  temp = idInit(IDELEMS(arg),arg->rank);
+  for (i=0;i<IDELEMS(arg);i++)
+  {
+    if (origR != syzstr->syRing)
+      temp->m[i] = prCopyR( arg->m[i], origR);
+    else
+      temp->m[i] = pCopy( arg->m[i]);
+    if (temp->m[i]!=NULL)
+    {
+      j = pTotaldegree(temp->m[i]);
+      if (j<actdeg) actdeg = j;
+    }
+  }
+  idTest(temp);
+  idSkipZeroes(temp);
+  syzstr->resPairs = syInitRes(temp,length,syzstr->Tl,syzstr->cw);
+  omFreeSize((ADDRESS)currcomponents,(arg->rank+1)*sizeof(int));
+  omFreeSize((ADDRESS)currShiftedComponents,(arg->rank+1)*sizeof(int));
+  syzstr->res = (resolvente)omAlloc0((*length+1)*sizeof(ideal));
+  syzstr->orderedRes = (resolvente)omAlloc0((*length+1)*sizeof(ideal));
+  syzstr->elemLength = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->truecomponents = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->backcomponents = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->ShiftedComponents = (long**)omAlloc0((*length+1)*sizeof(long*));
+  syzstr->Howmuch = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->Firstelem = (int**)omAlloc0((*length+1)*sizeof(int*));
+  syzstr->hilb_coeffs = (intvec**)omAlloc0((*length+1)*sizeof(intvec*));
+  syzstr->sev = (unsigned long **)omAlloc0((*length+1)*sizeof(unsigned long*));
+  syzstr->bucket = kBucketCreate();
+  syzstr->syz_bucket = kBucketCreate();
+  startdeg = actdeg;
+  nextPairs = syChosePairs(syzstr,&index,&howmuch,&actdeg);
+/*--- computes the resolution ----------------------*/
+  while (nextPairs!=NULL)
+  {
+#ifdef SHOW_PROT
+Print("compute %d Paare im Module %d im Grad %d \n",howmuch,index,actdeg+index);
+#endif
+    if (TEST_OPT_PROT) Print("%d",actdeg);
+    if (TEST_OPT_PROT) Print("(m%d)",index);
+    if (index==0)
+      i = syInitSyzMod(syzstr,index,idRankFreeModule(arg, origR)+1);
+    else
+      i = syInitSyzMod(syzstr,index);
+    j = syInitSyzMod(syzstr,index+1);
+    if (index>0)
+    {
+      syRedNextPairs_Hilb(nextPairs,syzstr,howmuch,index,actdeg,&toSub,&maxindex,&maxdeg);
+      sySetNewHilb(syzstr,toSub,index,actdeg);
+      toSub = 0;
+      syCompactifyPairSet(syzstr->resPairs[index],(*syzstr->Tl)[index],0);
+    }
+    else
+      syRedGenerOfCurrDeg_Hilb(syzstr,actdeg,&maxindex,&maxdeg);
+/*--- creates new pairs -----------------------------*/
+#ifdef SHOW_PROT
+Print("Bilde neue Paare in Modul %d!\n",index);
+#endif
+    syCreateNewPairs_Hilb(syzstr,index,actdeg);
+    if (index<(*length)-1)
+    {
+#ifdef SHOW_PROT
+Print("Bilde neue Paare in Modul %d!\n",index+1);
+#endif
+      syCreateNewPairs_Hilb(syzstr,index+1,actdeg-1);    }
+    index++;
+    nextPairs = syChosePairs(syzstr,&index,&howmuch,&actdeg);
+  }
+  syReOrdResult_Hilb(syzstr,maxindex,maxdeg);
+#ifdef SHOW_RESULT
+PrintS("minimal resolution:\n");
+for (int ti=1;ti<=*length;ti++)
+{
+  if (!idIs0(syzstr->orderedRes[ti])) idPrint(syzstr->orderedRes[ti]);
+}
+PrintS("full resolution:\n");
+for (int ti=1;ti<=*length;ti++)
+{
+  if (!idIs0(syzstr->res[ti])) idPrint(syzstr->res[ti]);
+}
+#endif
+#ifdef SHOW_CRIT
+Print("Criterion %d times applied\n",crit);
+Print("Criterion1 %d times applied\n",crit1);
+Print("%d superfluous pairs\n",spfl);
+Print("%d pairs considered\n",cons_pairs);
+Print("Criterion fails %d times\n",crit_fails);
+crit = 0;
+crit1 = 0;
+spfl = 0;
+cons_pairs = 0;
+crit_fails = 0;
+#endif
+  if (temp!=NULL) idDelete(&temp);
+  kBucketDestroy(&(syzstr->bucket));
+  kBucketDestroy(&(syzstr->syz_bucket));
+  if (origR != syzstr->syRing)  
+    rChangeCurrRing(origR);
+  else
+    currRing =  origR;
+  if (TEST_OPT_PROT) PrintLn();
+  return syzstr;
+}
Index: kernel/syz3.cc
===================================================================
--- kernel/syz3.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/syz3.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,2033 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: syz3.cc,v 1.1.1.1 2003-10-06 12:16:04 Singular Exp $ */
+/*
+* ABSTRACT: resolutions
+*/
+ 
+#include "mod2.h"
+#include <mylimits.h>
+#include "structs.h"
+//#include "attrib.h"
+#include "omalloc.h"
+#include "polys.h"
+#include "febase.h"
+#include "kstd1.h"
+#include "kutil.h"
+#include "stairc.h"
+//#include "cntrlc.h"
+#include "intvec.h"
+#include "numbers.h"
+#include "modulop.h"
+#include "ideals.h"
+#include "intvec.h"
+#include "ring.h"
+#include "syz.h"
+#include "kbuckets.h"
+#include "prCopy.h"
+#include "timer.h"
+#include "matpol.h"
+ 
+//#define SHOW_PROT
+//#define SHOW_RED
+//#define SHOW_Kosz
+//#define SHOW_RESULT
+//#define INVERT_PAIRS
+//#define ONLY_STD
+//#define EXPERIMENT1    //Hier stimmt was mit der Anzahl der Erzeuger in xyz11 nicht!!
+#define EXPERIMENT2
+#define EXPERIMENT3
+#define WITH_BUCKET     //Use of buckets in EXPERIMENT3 (Product criterion)
+#define WITH_SCHREYER_ORD
+#define USE_CHAINCRIT
+#define USE_CHAINCRIT0
+#define USE_PROD_CRIT
+#define USE_REGULARITY
+#define WITH_SORT
+//#define FULL_TOTAKE
+int discard_pairs;
+int short_pairs;
+ 
+/*3 
+* assumes the ideals old_ideal and new_ideal to be homogeneous
+* tests wether the new_ideal is a regular extension of the old_ideal
+*/
+static BOOLEAN syIsRegular(ideal old_ideal,ideal new_ideal,int deg)
+{
+  intvec * old_hilbs=hHstdSeries(old_ideal,NULL,NULL,NULL);
+  intvec * new_hilbs=hHstdSeries(new_ideal,NULL,NULL,NULL);
+  int biggest_length=si_max(old_hilbs->length()+deg,new_hilbs->length());
+  intvec * shifted_old_hilbs=new intvec(biggest_length);
+  intvec * old_hilb1=new intvec(biggest_length);
+  intvec * new_hilb1=new intvec(biggest_length);
+  int i;
+  BOOLEAN isRegular=TRUE;
+ 
+  for (i=old_hilbs->length()+deg-1;i>=deg;i--)
+    (*shifted_old_hilbs)[i] = (*old_hilbs)[i-deg];
+  for (i=old_hilbs->length()-1;i>=0;i--)
+    (*old_hilb1)[i] = (*old_hilbs)[i]-(*shifted_old_hilbs)[i];
+  for (i=old_hilbs->length()+deg-1;i>=old_hilbs->length();i--)
+    (*old_hilb1)[i] = -(*shifted_old_hilbs)[i];
+  for (i=new_hilbs->length()-1;i>=0;i--)
+    (*new_hilb1)[i] = (*new_hilbs)[i];
+  i = 0;
+  while ((i<biggest_length) && isRegular)
+  {
+    isRegular = isRegular && ((*old_hilb1)[i] == (*new_hilb1)[i]);
+    i++;
+  }
+  delete old_hilbs;
+  delete new_hilbs;
+  delete old_hilb1;
+  delete new_hilb1;
+  delete shifted_old_hilbs;
+  return isRegular;
+}
+ 
+/*3
+* shows the resolution stored in syzstr->orderedRes
+*/
+static void syShowRes(syStrategy syzstr)
+{
+  int i=0;
+ 
+  while ((i<syzstr->length) && (!idIs0(syzstr->res[i])))
+  {
+    Print("aktueller hoechster index ist: %d\n",(*syzstr->Tl)[i]);
+    Print("der %d-te modul ist:\n",i);
+    idPrint(syzstr->res[i]);
+    Print("Seine Darstellung:\n");
+    idPrint(syzstr->orderedRes[i]);
+    i++;
+  }
+}
+ 
+/*3
+* produces the next subresolution for a regular extension
+*/
+static void syCreateRegularExtension(syStrategy syzstr,ideal old_ideal,
+            ideal old_repr,int old_tl, poly next_generator,resolvente totake)
+{
+  int index=syzstr->length-1,i,j,start,start_ttk,new_tl;
+  poly gen=pCopy(next_generator),p;
+  poly neg_gen=pCopy(next_generator);
+  ideal current_ideal,current_repr;
+  int current_tl;
+  poly w_gen=pHead(next_generator);
+  pSetComp(w_gen,0);
+  pSetmComp(w_gen);
+  
+  //syShowRes(syzstr);
+  neg_gen = pNeg(neg_gen);
+  if (pGetComp(gen)>0)
+  {
+    pShift(&gen,-1);
+    pShift(&neg_gen,-1);
+  }
+  while (index>0) 
+  {
+    if (index%2==0)
+      p = gen;
+    else
+      p = neg_gen;
+    if (index>1)
+    {
+      current_ideal = syzstr->res[index-1];
+      current_repr = syzstr->orderedRes[index-1];
+      current_tl = (*syzstr->Tl)[index-1];
+    }
+    else
+    {
+      current_ideal = old_ideal;
+      current_repr = old_repr;
+      current_tl = old_tl;
+    }
+    if (!idIs0(current_ideal))
+    {
+      if (idIs0(syzstr->res[index]))
+      {
+        syzstr->res[index] = idInit(IDELEMS(current_ideal),
+          current_ideal->rank+current_tl);
+        syzstr->orderedRes[index] = idInit(IDELEMS(current_ideal),
+          current_ideal->rank);
+        start = 0;
+      }
+      else
+      {
+        start = IDELEMS(syzstr->res[index]);
+        while ((start>0) && (syzstr->res[index]->m[start-1]==NULL)) start--;
+        if (IDELEMS(syzstr->res[index])<start+IDELEMS(current_ideal))
+        {
+          pEnlargeSet(&syzstr->res[index]->m,IDELEMS(syzstr->res[index]),
+                   IDELEMS(current_ideal));
+          IDELEMS(syzstr->res[index]) += IDELEMS(current_ideal);
+          pEnlargeSet(&syzstr->orderedRes[index]->m,IDELEMS(syzstr->orderedRes[index]),
+                   IDELEMS(current_ideal));
+          IDELEMS(syzstr->orderedRes[index]) += IDELEMS(current_ideal);
+        }
+      }
+      if (idIs0(totake[index]))
+      {
+        totake[index] = idInit(IDELEMS(current_ideal),
+          current_ideal->rank+current_tl);
+        start_ttk = 0;
+      }
+      else
+      {
+        start_ttk = IDELEMS(totake[index]);
+        while ((start_ttk>0) && (totake[index]->m[start_ttk-1]==NULL)) start_ttk--;
+        if (IDELEMS(totake[index])<start_ttk+IDELEMS(current_ideal))
+        {
+          pEnlargeSet(&totake[index]->m,IDELEMS(totake[index]),
+                   IDELEMS(current_ideal));
+          for (j=IDELEMS(totake[index]);j<IDELEMS(totake[index])+
+                                  IDELEMS(current_ideal);j++)
+            totake[index]->m[j] = NULL;
+          IDELEMS(totake[index]) += IDELEMS(current_ideal);
+        }
+      }
+      for (i=0;i<IDELEMS(current_ideal);i++)
+      {
+        if (current_ideal->m[i]!=NULL)
+        {
+          syzstr->res[index]->m[i+start] = pCopy(current_ideal->m[i]);
+          syzstr->res[index]->m[i+start] = pMult_mm(syzstr->res[index]->m[i+start],w_gen);
+          pShift(&syzstr->res[index]->m[i+start],current_tl);
+          syzstr->res[index]->m[i+start] = pAdd(syzstr->res[index]->m[i+start],
+            ppMult_qq(current_repr->m[i],p));
+          syzstr->orderedRes[index]->m[i+start] = pCopy(current_repr->m[i]);
+          syzstr->orderedRes[index]->m[i+start] = 
+            pMult_mm(syzstr->orderedRes[index]->m[i+start],w_gen);
+          if ((*syzstr->Tl)[index]!=0)
+            pShift(&syzstr->orderedRes[index]->m[i+start],(*syzstr->Tl)[index]);
+        }
+      }
+      for (i=0;i<IDELEMS(totake[index-1]);i++)
+      {
+        if (totake[index-1]->m[i]!=NULL)
+        {
+          if ((index==1) && ((i==IDELEMS(current_ideal) ||
+               (totake[index-1]->m[i+1]==NULL)))) break;
+          totake[index]->m[i+start_ttk] = 
+            pMult_mm(pCopy(totake[index-1]->m[i]),w_gen);
+          pShift(&totake[index]->m[i+start_ttk],current_tl);
+#ifdef FULL_TOTAKE
+          poly pp=pCopy(p);
+          pShift(&pp,i+1);
+          totake[index]->m[i+start_ttk] = pAdd(totake[index]->m[i+start_ttk],pp);
+#endif
+        }
+      }
+      (*syzstr->Tl)[index] += current_tl;
+    }
+    index--;
+  }
+  pDelete(&gen);
+  pDelete(&neg_gen);
+  pDelete(&w_gen);
+  //syShowRes(syzstr);
+}
+ 
+/*3
+* proves the consistence of the pairset resPairs with the corresponding
+* set of generators;
+* only for tests
+*/
+static void syTestPairs(SSet resPairs,int length,ideal old_generators)
+{
+  int i=0;
+ 
+  while (i<length) 
+  {
+    if (resPairs[i].lcm!=NULL)
+    {
+      if (resPairs[i].p1!=NULL)
+        assume(resPairs[i].p1==old_generators->m[resPairs[i].ind1]);
+      if (resPairs[i].p2!=NULL)
+        assume(resPairs[i].p2==old_generators->m[resPairs[i].ind2]);
+    }
+    i++;
+  }
+}
+ 
+/*3
+* cancels the weight monomials given by the leading terms of totake
+* from the resolution res;
+* works in place on res, but reads only from totake
+*/
+void syReorder_Kosz(syStrategy syzstr)
+{
+  int length=syzstr->length;
+  int syzIndex=length-1,i,j;
+  resolvente res=syzstr->fullres;
+  poly p;
+ 
+  while ((syzIndex!=0) && (res[syzIndex]==NULL)) syzIndex--;
+  while (syzIndex>0)
+  {
+    for(i=0;i<IDELEMS(res[syzIndex]);i++)
+    {
+#ifdef USE_REGULARITY
+      if ((syzstr->regularity>0) && (res[syzIndex]->m[i]!=NULL))
+      {
+        if (pFDeg(res[syzIndex]->m[i])>=syzstr->regularity+syzIndex)
+          pDelete(&res[syzIndex]->m[i]);
+      }
+#endif
+      p = res[syzIndex]->m[i];
+      while (p!=NULL)
+      {
+        if (res[syzIndex-1]->m[pGetComp(p)-1]!=NULL)
+        {
+          for(j=1;j<=pVariables;j++)
+          {
+            pSetExp(p,j,pGetExp(p,j)
+                        -pGetExp(res[syzIndex-1]->m[pGetComp(p)-1],j));
+          }
+        }
+        else
+          PrintS("error in the resolvent\n");
+        pSetm(p);
+        pIter(p);
+      }
+    }
+    syzIndex--;
+  }
+}
+ 
+/*3
+* updates the pairset resPairs by generating all pairs including the
+* new_generators in the 0-th modul;
+* the new_generators are inserted in the old_generators;
+* new_generators is empty after the procedure;
+*/
+static void updatePairs(SSet *resPairs,int *l_pairs,syStrategy syzstr,
+       int index,ideal new_generators,ideal new_repr,int crit_comp)
+{
+  if (idIs0(new_generators)) return;
+  ideal old_generators=syzstr->res[index];
+  ideal old_repr=syzstr->orderedRes[index];
+  int i=0,j,k,kk,og_elem=0,og_idel=IDELEMS(old_generators),l=*l_pairs,jj,ll,j1;
+  int og_ini=0;
+  ideal pairs=idInit(og_idel+IDELEMS(new_generators),old_generators->rank);
+  polyset prs=pairs->m;
+  poly p=NULL;
+  SObject tso;
+ 
+  syInitializePair(&tso);
+  while ((og_elem<og_idel) && (old_generators->m[og_elem]!=NULL)) 
+  {
+    if ((index>0) && (pGetComp(old_generators->m[og_elem])<=crit_comp))
+      og_ini = og_elem;
+    og_elem++;
+  }
+  while ((l>0) && ((*resPairs)[l-1].lcm==NULL)) l--;
+  while ((i<IDELEMS(new_generators)) && (new_generators->m[i]!=NULL))
+  {
+    syTestPairs(*resPairs,*l_pairs,old_generators);
+    if (IDELEMS(old_generators)==og_elem)
+    {
+      pEnlargeSet(&old_generators->m,IDELEMS(old_generators),16);
+      IDELEMS(old_generators) += 16;
+      pEnlargeSet(&old_repr->m,IDELEMS(old_repr),16);
+      IDELEMS(old_repr) += 16;
+    }
+    k = pFDeg(new_generators->m[i]);
+    kk = pGetComp(new_generators->m[i]);
+    j = og_ini;
+    while ((j<og_elem) && (old_generators->m[j]!=NULL) &&
+           (pGetComp(old_generators->m[j])<kk)) j++;
+    while ((j<og_elem) && (old_generators->m[j]!=NULL) &&
+           (pFDeg(old_generators->m[j])<=k)) j++;
+    for (jj=og_elem;jj>j;jj--)
+    {
+      old_generators->m[jj] = old_generators->m[jj-1];
+      old_repr->m[jj] = old_repr->m[jj-1];
+    }
+    old_generators->m[j] = new_generators->m[i];
+    new_generators->m[i] = NULL;
+    old_repr->m[j] = new_repr->m[i];
+    new_repr->m[i] = NULL;
+    og_elem++;
+    for (jj=0;jj<*l_pairs;jj++)
+    {
+      if ((*resPairs)[jj].lcm!=NULL)
+      {
+        if ((*resPairs)[jj].ind1>=j) (*resPairs)[jj].ind1++;
+        if ((*resPairs)[jj].ind2>=j) (*resPairs)[jj].ind2++;
+      }
+    }
+    syTestPairs(*resPairs,*l_pairs,old_generators);
+    for (jj=og_ini;jj<og_elem;jj++)
+    {
+      if ((j!=jj) && (pGetComp(old_generators->m[jj])==pGetComp(old_generators->m[j])))
+      {
+        p = pOne();
+        pLcm(old_generators->m[jj],old_generators->m[j],p);
+        pSetComp(p,j+1);
+        pSetm(p);
+        j1 = 0;
+        while (j1<jj)
+        {
+          if (prs[j1]!=NULL)
+          {
+            if (pLmDivisibleByNoComp(prs[j1],p))
+            {
+              pDelete(&p);
+              break;
+            }
+            else if (pLmDivisibleByNoComp(p,prs[j1]))
+            {
+              pDelete(&(prs[j1]));
+            }
+#ifdef USE_CHAINCRIT0
+            else
+            {
+              poly p1,p2;
+              int ip=pVariables;
+              p1 = pDivide(p,old_generators->m[jj]);
+              p2 = pDivide(prs[j1],old_generators->m[j1]);
+              while ((ip>0) && (pGetExp(p1,ip)*pGetExp(p2,ip)==0)) ip--;
+              if (ip==0)
+              {
+                int ti=0;
+                while ((ti<l) && (((*resPairs)[ti].ind1!=j1)|| ((*resPairs)[ti].ind2!=jj))) ti++;
+                if (ti<l) 
+                {
+                  if (TEST_OPT_PROT) Print("cc");
+                  syDeletePair(&(*resPairs)[ti]);
+                  syCompactifyPairSet(*resPairs,*l_pairs,ti);
+                  l--;
+                }
+              }
+              pDelete(&p1);
+              pDelete(&p2);
+            }
+#endif
+          }
+          j1++;
+        }
+        if (p!=NULL)
+          prs[jj] = p;
+      }
+    }
+    for (jj=og_ini;jj<og_elem;jj++)
+    {
+      if (prs[jj] !=NULL)
+      {
+        if (l>=*l_pairs)
+        {
+          SSet temp = (SSet)omAlloc0((*l_pairs+16)*sizeof(SObject));
+          for (ll=0;ll<*l_pairs;ll++)
+          {
+            temp[ll].p = (*resPairs)[ll].p;
+            temp[ll].p1 = (*resPairs)[ll].p1;
+            temp[ll].p2 = (*resPairs)[ll].p2;
+            temp[ll].syz = (*resPairs)[ll].syz;
+            temp[ll].lcm = (*resPairs)[ll].lcm;
+            temp[ll].ind1 = (*resPairs)[ll].ind1;
+            temp[ll].ind2 = (*resPairs)[ll].ind2;
+            temp[ll].syzind = (*resPairs)[ll].syzind;
+            temp[ll].order = (*resPairs)[ll].order;
+            temp[ll].isNotMinimal = (*resPairs)[ll].isNotMinimal;
+          }
+          omFreeSize((ADDRESS)(*resPairs),*l_pairs*sizeof(SObject));
+          *l_pairs += 16;
+          (*resPairs) = temp;
+        }
+        tso.lcm = prs[jj];
+        prs[jj] = NULL;
+        tso.order = pFDeg(tso.lcm);
+        tso.p1 = old_generators->m[jj];
+        tso.p2 = old_generators->m[j];
+        tso.ind1 = jj;
+        tso.ind2 = j;
+        tso.syzind = -1;
+        tso.isNotMinimal = NULL;
+        tso.p = NULL;
+        tso.syz = NULL;
+        SSet rP=*resPairs;
+#ifdef SHOW_PROT
+Print("erzeuge Paar im Modul %d,%d mit: \n",index,tso.order);
+Print("poly1: ");pWrite(tso.p1);
+Print("poly2: ");pWrite(tso.p2);
+Print("syz: ");pWrite(tso.syz);
+Print("sPoly: ");pWrite(tso.p);
+PrintLn();
+#endif
+        syEnterPair(rP,&tso,&l,index);
+        syInitializePair(&tso);
+      }
+    }
+    i++;
+  }
+  idDelete(&pairs);
+}
+ 
+/*3
+* performs the modification of a single reduction on the syzygy-level
+*/
+inline void sySPRedSyz_Kosz(syStrategy syzstr,poly redWith,poly syz,poly q=NULL,int l_syz=-1)
+{
+  poly p=pDivide(q,redWith);
+  pSetCoeff(p,nDiv(pGetCoeff(q),pGetCoeff(redWith)));
+  kBucket_Minus_m_Mult_p(syzstr->syz_bucket,p,syz,&l_syz,NULL);
+  pDelete(&p);
+}
+ 
+/*3
+* normalizes the poly bucket by the ideal;
+* stops the reduction whenever the leading component is less than the
+* crit_comp;
+* returns the changing status
+*/
+static BOOLEAN syRedSyz(kBucket_pt bucket,ideal red,int crit_comp,int* g_l)
+{
+  poly p = kBucketGetLm(bucket);
+  int j = 0,i=IDELEMS(red)-1;
+  number n;
+  BOOLEAN isChanged=FALSE;
+ 
+  loop
+  {
+    if ((j>=i) || (p==NULL) || (pGetComp(p)<=crit_comp)) break;
+    if ((red->m[j]!=NULL) && (pDivisibleBy(red->m[j],p)))
+    {
+      n = kBucketPolyRed(bucket,red->m[j], g_l[j], NULL);
+      nDelete(&n);
+      p = kBucketGetLm(bucket);
+      isChanged = TRUE;
+      j = 0;
+    }
+    else
+      j++;
+  }
+  return isChanged;
+}
+ 
+/*3
+* a tail reduction for the syzygies yielding new generators
+*/
+static poly syRedTailSyz(poly tored,ideal red,ideal sec_red,int crit_comp,syStrategy syzstr,
+            int * gen_length,int * secgen_length,int * tored_length)
+{
+  int i=IDELEMS(red)-1,num_mon,num_tail;
+  poly h,hn;
+  BOOLEAN dummy;
+ 
+  while ((i>0) && (red->m[i-1]==NULL)) i--;
+  i--;
+  h = tored;
+  if ((h!=NULL) && (pGetComp(h)>crit_comp))
+  {
+    num_mon = 1;
+    hn = pNext(h);
+    num_tail = *tored_length-1;
+    while (hn!=NULL)
+    {
+      kBucketInit(syzstr->syz_bucket,hn,num_tail);
+      dummy = syRedSyz(syzstr->syz_bucket,red,crit_comp,gen_length);
+      kBucketClear(syzstr->syz_bucket,&hn,&num_tail);
+      pNext(h) = hn;
+      if ((hn==NULL) || (pGetComp(hn)<=crit_comp))
+        break;
+      else
+      {
+        pIter(h);
+        pIter(hn);
+        num_mon++;
+        num_tail--;
+      }
+    }
+    if (sec_red!=NULL)
+    {
+      while (hn!=NULL)
+      {
+        kBucketInit(syzstr->syz_bucket,hn,num_tail);
+        dummy = syRedSyz(syzstr->syz_bucket,sec_red,crit_comp,secgen_length);
+        kBucketClear(syzstr->syz_bucket,&hn,&num_tail);
+        pNext(h) = hn;
+        if (hn==NULL)
+          break;
+        else
+        {
+          pIter(h);
+          pIter(hn);
+          num_mon++;
+          num_tail--;
+        }
+      }
+    }
+    *tored_length = num_mon+num_tail;
+  }
+  assume(pLength(tored)==*tored_length);
+  return tored;
+}
+ 
+/*3
+* the complete reduction of a single pair which is just stored
+* in bucket and syz_bucket 
+*/
+static BOOLEAN syRedSyzPair(syStrategy syzstr,int index,int* g_l,int* orp_l)
+{
+  kBucket_pt bucket=syzstr->bucket;
+  poly p = kBucketGetLm(bucket);
+  ideal red=syzstr->res[index],repr=syzstr->orderedRes[index];
+  int j = 0,i=IDELEMS(red)-1;
+  number n;
+  BOOLEAN isChanged=FALSE;
+ 
+  loop
+  {
+    if ((j>=i) || (p==NULL)) break;
+    if ((red->m[j]!=NULL) && (pDivisibleBy(red->m[j],p)))
+    {
+      sySPRedSyz_Kosz(syzstr,red->m[j],repr->m[j],p,orp_l[j]);
+      n = kBucketPolyRed(bucket,red->m[j], g_l[j], NULL);
+      nDelete(&n);
+      p = kBucketGetLm(bucket);
+      isChanged = TRUE;
+      j = 0;
+    }
+    else
+      j++;
+  }
+  return isChanged;
+}
+ 
+/*3
+* the tailreduction for generators (which includes the correction of
+* the corresponding representation)
+*/
+static void syRedTailSyzPair(SObject tso,syStrategy syzstr,int index,
+            int * gen_length,int* orp_l,int * tored_l,int * syzred_l)
+{
+  int num_mon,num_tail,syz_l;
+  poly h,hn;
+  BOOLEAN dummy;
+ 
+  h = tso.p;
+  kBucketInit(syzstr->syz_bucket,tso.syz,*syzred_l);
+  if (h!=NULL)
+  {
+    num_mon = 1;
+    hn = pNext(h);
+    num_tail = *tored_l-1;
+    while (hn!=NULL)
+    {
+      kBucketInit(syzstr->bucket,hn,num_tail);
+      dummy = syRedSyzPair(syzstr,index,gen_length,orp_l);
+      kBucketClear(syzstr->bucket,&hn,&num_tail);
+      pNext(h) = hn;
+      if (hn==NULL)
+        break;
+      else
+      {
+        pIter(h);
+        pIter(hn);
+        num_mon++;
+        num_tail--;
+      }
+    }
+    *tored_l = num_mon+num_tail;
+  }
+  kBucketClear(syzstr->syz_bucket,&tso.syz,&syz_l);
+  assume(pLength(tso.syz)==syz_l);
+  assume(pLength(tso.p)==*tored_l);
+}
+ 
+/*3
+* the reduction of a pair in the 0-th module
+*/
+static void redOnePair(SSet resPairs,int itso,int l, ideal syzygies, 
+            int crit_comp, syStrategy syzstr,int index,ideal new_generators,
+            ideal new_repr,int * ogm_l,int * orp_l)
+{
+  SObject tso = resPairs[itso];
+  assume (tso.lcm!=NULL);
+  ideal old_generators=syzstr->res[index];
+  ideal old_repr=syzstr->orderedRes[index];
+  int og_idel=IDELEMS(old_generators),ng_place=IDELEMS(new_generators);
+  int toReplace=0;
+  int i,j,syz_l;
+  number coefgcd,n;
+  polyset ogm=old_generators->m;
+  poly p;
+  BOOLEAN deleteP=FALSE;
+#ifdef EXPERIMENT1
+  poly syzp;
+#endif
+  int syz_place=IDELEMS(syzygies);
+ 
+  while ((syz_place>0) && (syzygies->m[syz_place-1]==NULL)) syz_place--;
+  while ((ng_place>0) && (new_generators->m[ng_place-1]==NULL)) ng_place--;
+  while ((og_idel>0) && (old_generators->m[og_idel-1]==NULL)) og_idel--;
+  assume (tso.ind1<og_idel);
+  assume (tso.ind2<og_idel);
+  assume (tso.ind1!=tso.ind2);
+  assume (tso.p1 == old_generators->m[tso.ind1]);
+  assume (tso.p2 == old_generators->m[tso.ind2]);
+  tso.p1 = old_generators->m[tso.ind1];
+  tso.p2 = old_generators->m[tso.ind2];
+  if ((tso.p1!=NULL) && (tso.p2!=NULL))
+  {
+    if (TEST_OPT_PROT)
+      Print(".");
+    if (index==0)
+    {
+/*--- tests wether a generator must be replaced (lt(f1)|lt(f2)!)--*/
+      if (pFDeg(tso.p1)==pFDeg(tso.lcm))
+        toReplace = tso.ind1+1;
+      else if (pFDeg(tso.p2)==pFDeg(tso.lcm))
+        toReplace = tso.ind2+1;
+    }
+#ifdef EXPERIMENT3
+/*--- tests wether the product criterion applies --------------*/
+    if ((index==0) && (old_generators->rank==1) && 
+        (pFDeg(tso.p1)+pFDeg(tso.p2)==tso.order))
+    {
+      tso.p = NULL;
+      p = pCopy(tso.p1);
+      pShift(&p,-1);
+#ifdef WITH_BUCKET
+      poly pp;
+      pp = pMult_mm(pCopy(old_repr->m[tso.ind2]),p);
+      kBucketInit(syzstr->syz_bucket,pp,-1);
+      pDeleteLm(&p);
+      p = pNeg(p);
+      pp = pCopy(old_repr->m[tso.ind2]);
+      int il=-1;
+      while (p!=NULL)
+      {
+        kBucket_Minus_m_Mult_p(syzstr->syz_bucket,p,pp,&il,NULL);
+        pDeleteLm(&p);
+      }
+      pDelete(&pp);
+      p = pCopy(tso.p2);
+      pShift(&p,-1);
+      pp = pCopy(old_repr->m[tso.ind1]);
+      il=-1;
+      while (p!=NULL)
+      {
+        kBucket_Minus_m_Mult_p(syzstr->syz_bucket,p,pp,&il,NULL);
+        pDeleteLm(&p);
+      }
+      pDelete(&pp);
+      kBucketClear(syzstr->syz_bucket,&tso.syz,&j);
+#else
+      tso.syz = pMult(p,pCopy(old_repr->m[tso.ind2]));
+      p = pCopy(tso.p2);
+      pShift(&p,-1);
+      tso.syz = pSub(tso.syz,pMult(p,pCopy(old_repr->m[tso.ind1])));
+#endif
+    }
+    else
+#endif
+/*--- the product criterion does not apply --------------------*/
+    {
+      tso.p = ksOldCreateSpoly(tso.p2,tso.p1);
+      number coefgcd = nGcd(pGetCoeff(tso.p1),pGetCoeff(tso.p2),currRing);
+      assume (old_repr->m[tso.ind1]!=NULL);
+      tso.syz = pCopy(old_repr->m[tso.ind1]);
+      poly tt = pDivide(tso.lcm,tso.p1);
+      pSetComp(tt,0);
+      pSetmComp(tt);
+      pSetCoeff(tt,nDiv(pGetCoeff(tso.p1),coefgcd));
+      tso.syz = pMult_mm(tso.syz,tt);
+      pDelete(&tt);
+      coefgcd = nNeg(coefgcd);
+      assume (old_repr->m[tso.ind2]!=NULL);
+      p = pCopy(old_repr->m[tso.ind2]);
+      tt = pDivide(tso.lcm,tso.p2);
+      pSetComp(tt,0);
+      pSetmComp(tt);
+      pSetCoeff(tt,nDiv(pGetCoeff(tso.p2),coefgcd));
+      p = pMult_mm(p,tt);
+      pDelete(&tt);
+      tso.syz = pAdd(p,tso.syz);
+#ifdef EXPERIMENT2
+      if ((tso.syz!=NULL) && (pGetComp(tso.syz)<=crit_comp)) 
+      {
+/*--- breaks when the leading component is less than crit_comp ------*/
+        deleteP = TRUE;
+        discard_pairs++;
+      }
+#endif
+      nDelete(&coefgcd);
+    }                             //End of the else-part of EXPERIMENT3
+#ifdef SHOW_PROT
+Print("reduziere Paar im Module %d mit: \n",index);
+Print("poly1: ");pWrite(tso.p1);
+Print("poly2: ");pWrite(tso.p2);
+Print("syz: ");pWrite(tso.syz);
+Print("sPoly: ");pWrite(tso.p);
+#endif
+    assume(tso.syz!=NULL);
+    kBucketInit(syzstr->syz_bucket,tso.syz,-1);
+    if ((tso.p!=NULL) && (!deleteP))
+    {
+      kBucketInit(syzstr->bucket,tso.p,-1);
+      p = kBucketGetLm(syzstr->bucket);
+      j = 0;
+      loop
+      {
+        if (j>=og_idel) 
+        {
+/*--- reduction with generators computed in this procedure ---*/
+          j = 0;
+          while ((j<ng_place) && (!pDivisibleBy(new_generators->m[j],p))) j++;
+          if (j>=ng_place) break;
+          assume (new_repr->m[j]!=NULL);
+          sySPRedSyz_Kosz(syzstr,new_generators->m[j],new_repr->m[j],p);
+          n = kBucketPolyRed(syzstr->bucket,new_generators->m[j],pLength(new_generators->m[j]), NULL);
+          p = kBucketGetLm(syzstr->bucket);
+#ifdef EXPERIMENT1
+          syzp = kBucketGetLm(syzstr->syz_bucket);
+          if ((syzp!=NULL) && (pGetComp(syzp)<=crit_comp))
+          {
+            deleteP =TRUE;
+            break;
+          }
+          //if (syzp==NULL) 
+            //assume(p==NULL);
+          //else 
+            //if (pGetComp(syzp)<=crit_comp) short_pairs++;
+#endif
+          if (p==NULL) break;
+          j = 0;
+        }
+        if (pDivisibleBy(ogm[j],p))
+        {
+/*--- reduction with general old generators ---------------------*/
+          assume (old_repr->m[j]!=NULL);
+          sySPRedSyz_Kosz(syzstr,ogm[j],old_repr->m[j],p,orp_l[j]);
+          n = kBucketPolyRed(syzstr->bucket,ogm[j],ogm_l[j], NULL);
+          p = kBucketGetLm(syzstr->bucket);
+#ifdef EXPERIMENT1
+          syzp = kBucketGetLm(syzstr->syz_bucket);
+          if ((syzp!=NULL) && (pGetComp(syzp)<=crit_comp))
+          {
+            break;
+            deleteP =TRUE;
+          }
+          //if (syzp==NULL) 
+            //assume(p==NULL);
+          //else 
+            //if ((pGetComp(syzp)<=crit_comp) && (p!=NULL)) short_pairs++;
+#endif
+          if (p==NULL) break;
+          j = 0;
+        }
+        else
+          j++;
+      }
+      kBucketClear(syzstr->bucket,&tso.p,&tso.length);
+    }
+    kBucketClear(syzstr->syz_bucket,&tso.syz,&syz_l);
+    if (deleteP)
+    {
+      pDelete(&tso.p);
+      pDelete(&tso.syz);
+    }
+  }
+  else
+  {
+    Print("Shit happens!\n");
+  }
+#ifdef SHOW_PROT
+Print("erhalte Paar im Module %d mit: \n",index);
+Print("syz: ");pWrite(tso.syz);
+Print("sPoly: ");pWrite(tso.p);
+PrintLn();
+#endif
+  if (toReplace)
+  {
+/*-- replaces the generator if neccesary ------------------*/
+    pDelete(&old_generators->m[toReplace-1]);
+    pDelete(&old_repr->m[toReplace-1]);
+    for (i=toReplace-1;i<og_idel-1;i++)
+    {
+      old_generators->m[i] = old_generators->m[i+1];
+      old_repr->m[i] = old_repr->m[i+1];
+    }
+    old_generators->m[og_idel-1] = NULL;
+    old_repr->m[og_idel-1] = NULL;
+    for (i=itso+1;i<l;i++)
+    {
+      if (resPairs[i].lcm!=NULL) 
+      { 
+        if ((resPairs[i].ind1==toReplace-1)||(resPairs[i].ind2==toReplace-1))
+          syDeletePair(&resPairs[i]);
+        else 
+        {
+          if (resPairs[i].ind1>=toReplace)
+            (resPairs[i].ind1)--;
+          if (resPairs[i].ind2>=toReplace)
+            (resPairs[i].ind2)--;
+        }
+      }
+    }
+    syCompactifyPairSet(resPairs,l,itso+1);
+  }
+  if (tso.p!=NULL)
+  {
+/*-- stores the new generator ---------------------------------*/
+    //syRedTailSyzPair(tso,syzstr,index,ogm_l,orp_l,&tso.length,&syz_l);
+    if (ng_place>=IDELEMS(new_generators))
+    {
+      pEnlargeSet(&new_generators->m,IDELEMS(new_generators),16);
+      IDELEMS(new_generators) += 16;
+      pEnlargeSet(&new_repr->m,IDELEMS(new_repr),16);
+      IDELEMS(new_repr) += 16;
+    }
+    if (!nIsOne(pGetCoeff(tso.p)))
+    {
+      n=nInvers(pGetCoeff(tso.p));
+      pNorm(tso.p);
+      pMult_nn(tso.syz,n);
+      nDelete(&n);
+    }
+    new_generators->m[ng_place] = tso.p;
+    tso.p = NULL;
+    new_repr->m[ng_place] = tso.syz;
+    tso.syz = NULL;
+  }
+  else
+  {
+/*--- takes the syzygy as new generator of the next module ---*/
+    if (tso.syz==NULL)
+    {
+#ifndef EXPERIMENT2
+#ifdef EXPERIMENT3
+      short_pairs++;
+#endif
+#endif
+    }
+    else if (pGetComp(tso.syz)<=crit_comp)
+    {
+      pDelete(&tso.syz);
+    }
+    else
+    {
+      if (syz_place>=IDELEMS(syzygies))
+      {
+        pEnlargeSet(&syzygies->m,IDELEMS(syzygies),16);
+        IDELEMS(syzygies) += 16;
+      }
+      syzygies->m[syz_place] = tso.syz;
+      tso.syz = NULL;
+      pNorm(syzygies->m[syz_place]);
+    }
+  }
+  resPairs[itso] = tso;
+  syDeletePair(&resPairs[itso]);
+  syTestPairs(resPairs,l,old_generators);
+}
+ 
+/*3
+* reduction of all pairs of a fixed degree of the 0-th module
+*/
+static BOOLEAN redPairs(SSet resPairs,int l_pairs, ideal syzygies,
+  ideal new_generators,ideal new_repr, int crit_comp,syStrategy syzstr,
+  int index)
+{
+  if (resPairs[0].lcm==NULL) return TRUE;
+  int i,j,actdeg=resPairs[0].order;
+  int * ogm_l=(int*)omAlloc0(IDELEMS(syzstr->res[index])*sizeof(int));
+  int * orp_l=(int*)omAlloc0(IDELEMS(syzstr->orderedRes[index])*sizeof(int));
+  int t1=IDELEMS(syzstr->res[index]),t2=IDELEMS(syzstr->orderedRes[index]);
+ 
+  for (j=IDELEMS(syzstr->res[index])-1;j>=0;j--) 
+  {
+    if (syzstr->res[index]->m[j]!=NULL)
+      ogm_l[j] = pLength(syzstr->res[index]->m[j]);
+  }
+  for (j=IDELEMS(syzstr->orderedRes[index])-1;j>=0;j--) 
+  {
+    if (syzstr->orderedRes[index]->m[j]!=NULL)
+      orp_l[j] = pLength(syzstr->orderedRes[index]->m[j]);
+  }
+  loop
+  {
+    i = 0;
+    if (TEST_OPT_PROT)
+      Print("(%d,%d)",index,resPairs[0].order);
+    while (resPairs[i].order==actdeg)
+    {
+      syTestPairs(resPairs,l_pairs,syzstr->res[index]);
+      redOnePair(resPairs,i,l_pairs,syzygies,crit_comp,syzstr,index,
+                 new_generators, new_repr,ogm_l,orp_l);
+      i++;
+      syTestPairs(resPairs,l_pairs,syzstr->res[index]);
+    }
+    syTestPairs(resPairs,l_pairs,syzstr->res[index]);
+    syCompactifyPairSet(resPairs,l_pairs,0);
+    syTestPairs(resPairs,l_pairs,syzstr->res[index]);
+    if (!idIs0(new_generators))
+      break;
+    else if (resPairs[0].lcm==NULL)  //there are no pairs left and no new_gens
+    {
+      omFreeSize((ADDRESS)ogm_l,IDELEMS(syzstr->res[index])*sizeof(int));
+      omFreeSize((ADDRESS)orp_l,IDELEMS(syzstr->orderedRes[index])*sizeof(int));
+      return TRUE;
+    }
+    else
+      actdeg = resPairs[0].order;
+  }
+  syTestPairs(resPairs,l_pairs,syzstr->res[index]);
+  omFreeSize((ADDRESS)ogm_l,IDELEMS(syzstr->res[index])*sizeof(int));
+  omFreeSize((ADDRESS)orp_l,IDELEMS(syzstr->orderedRes[index])*sizeof(int));
+  return FALSE;
+}
+ 
+/*3
+* extends the standard basis old_generators with new_generators;
+* returns the syzygies which involve the new elements;
+* assumes that the components of the new_generators are sperated
+* from those of old_generators, i.e. whenever the leading term
+* of a syzygy lies in the part of the old_generators, the syzygy 
+* lie just in the module old_generators 
+* assumes that the new_generators are reduced w.r.t. old_generators
+*/
+static ideal kosz_std(ideal new_generators,ideal new_repr,syStrategy syzstr,
+                      int index,int next_comp)
+{
+  int og_idel=IDELEMS(syzstr->res[index]);
+  int l_pairs=2*og_idel;
+  ideal syzygies=idInit(16,syzstr->res[index]->rank+1);
+  if ((idIs0(new_generators)) || (new_generators->m[0]==NULL))
+  {
+    Werror("Hier ist was faul!\n");
+    return NULL;
+  }
+  SSet resPairs=(SSet)omAlloc0(l_pairs*sizeof(SObject));
+  loop
+  {
+    updatePairs(&resPairs,&l_pairs,syzstr,index,
+                new_generators,new_repr,next_comp);
+    if (redPairs(resPairs,l_pairs,syzygies, new_generators,new_repr,
+                 next_comp,syzstr,index)) break;
+  }
+  omFreeSize((SSet)resPairs,l_pairs*sizeof(SObject));
+  return syzygies;
+}
+ 
+/*3
+* normalizes the incoming generators
+*/
+static poly normalize(poly next_p,ideal add_generators, syStrategy syzstr,
+                      int * g_l,int * p_l,int crit_comp)
+{
+  int j=0,i=IDELEMS(add_generators);
+  kBucketInit(syzstr->bucket,next_p,pLength(next_p));
+  poly p = kBucketGetLm(syzstr->bucket),result;
+  number n;
+ 
+  loop
+  {
+    if ((j>=i) || (p==NULL) || (pGetComp(p)<=crit_comp)) break;
+    if ((add_generators->m[j]!=NULL) && (pDivisibleBy(add_generators->m[j],p)))
+    {
+      n = kBucketPolyRed(syzstr->bucket,add_generators->m[j], g_l[j], NULL);
+      nDelete(&n);
+      p = kBucketGetLm(syzstr->bucket);
+      j = 0;
+    }
+    else
+      j++;
+  }
+  kBucketClear(syzstr->bucket,&result,p_l);
+  return result;
+}
+ 
+/*3
+* updates the pairs inthe higher modules
+*/
+static void updatePairsHIndex(SSet *resPairs,int *l_pairs,syStrategy syzstr,
+       int index,ideal add_generators,ideal add_repr,ideal new_generators,
+       ideal new_repr,int crit_comp,int* first_new)
+{
+  int i=*first_new,l=*l_pairs,j,ll,j1,add_idel=IDELEMS(add_generators);
+  ideal pairs=idInit(add_idel,add_generators->rank);
+  polyset prs=pairs->m;
+  poly p=NULL;
+  SObject tso;
+ 
+  syInitializePair(&tso);
+  while ((l>0) && ((*resPairs)[l-1].lcm==NULL)) l--;
+  while ((i<add_idel) && (add_generators->m[i]!=NULL))
+  {
+    for (j=0;j<i;j++)
+    {
+      if ((pGetComp(add_generators->m[j])==pGetComp(add_generators->m[i])))
+      {
+        p = pOne();
+        pLcm(add_generators->m[j],add_generators->m[i],p);
+        pSetComp(p,i+1);
+        pSetm(p);
+        j1 = 0;
+        while (j1<j)
+        {
+          if (prs[j1]!=NULL)
+          {
+            if (pLmDivisibleByNoComp(prs[j1],p))
+            {
+              pDelete(&p);
+              break;
+            }
+            else if (pLmDivisibleByNoComp(p,prs[j1]))
+            {
+              pDelete(&(prs[j1]));
+            }
+#ifdef USE_CHAINCRIT
+            else
+            {
+              poly p1,p2;
+              int ip=pVariables;
+              p1 = pDivide(p,add_generators->m[j]);
+              p2 = pDivide(prs[j1],add_generators->m[j1]);
+              while ((ip>0) && (pGetExp(p1,ip)*pGetExp(p2,ip)==0)) ip--;
+              if (ip==0)
+              {
+                int ti=0;
+                while ((ti<l) && (((*resPairs)[ti].ind1!=j1)|| ((*resPairs)[ti].ind2!=j))) ti++;
+                if (ti<l) 
+                {
+                  if (TEST_OPT_PROT) Print("cc");
+                  syDeletePair(&(*resPairs)[ti]);
+                  syCompactifyPairSet(*resPairs,*l_pairs,ti);
+                  l--;
+                }
+              }
+              pDelete(&p1);
+              pDelete(&p2);
+            }
+#endif
+          }
+          j1++;
+        }
+        if (p!=NULL)
+          prs[j] = p;
+      }
+    }
+    for (j=0;j<i;j++)
+    {
+      if (prs[j] !=NULL)
+      {
+        if (l>=*l_pairs)
+        {
+          SSet temp = (SSet)omAlloc0((*l_pairs+16)*sizeof(SObject));
+          for (ll=0;ll<*l_pairs;ll++)
+          {
+            temp[ll].p = (*resPairs)[ll].p;
+            temp[ll].p1 = (*resPairs)[ll].p1;
+            temp[ll].p2 = (*resPairs)[ll].p2;
+            temp[ll].syz = (*resPairs)[ll].syz;
+            temp[ll].lcm = (*resPairs)[ll].lcm;
+            temp[ll].ind1 = (*resPairs)[ll].ind1;
+            temp[ll].ind2 = (*resPairs)[ll].ind2;
+            temp[ll].syzind = (*resPairs)[ll].syzind;
+            temp[ll].order = (*resPairs)[ll].order;
+            temp[ll].isNotMinimal = (*resPairs)[ll].isNotMinimal;
+          }
+          omFreeSize((ADDRESS)(*resPairs),*l_pairs*sizeof(SObject));
+          *l_pairs += 16;
+          (*resPairs) = temp;
+        }
+        tso.lcm = prs[j];
+        prs[j] = NULL;
+        tso.order = pFDeg(tso.lcm);
+        tso.p1 = add_generators->m[j];
+        tso.p2 = add_generators->m[i];
+        tso.ind1 = j;
+        tso.ind2 = i;
+        tso.syzind = -1;
+        tso.isNotMinimal = NULL;
+        tso.p = NULL;
+        tso.syz = NULL;
+        SSet rP=*resPairs;
+#ifdef SHOW_PROT
+Print("erzeuge Paar im Modul %d,%d mit: \n",index,tso.order);
+Print("poly1: ");pWrite(tso.p1);
+Print("poly2: ");pWrite(tso.p2);
+Print("syz: ");pWrite(tso.syz);
+Print("sPoly: ");pWrite(tso.p);
+PrintLn();
+#endif
+        syEnterPair(rP,&tso,&l,index);
+        syInitializePair(&tso);
+      }
+    }
+    i++;
+  }
+  *first_new = i;
+  idDelete(&pairs);
+}
+ 
+/*3
+* reduction of a single pair in the higher moduls
+*/
+static void redOnePairHIndex(SSet resPairs,int itso, int crit_comp, 
+            syStrategy syzstr,int index,ideal add_generators, ideal add_repr,
+            ideal new_generators, ideal new_repr,int * next_place_add,int ** g_l,
+            poly deg_soc)
+{
+  SObject tso = resPairs[itso];
+  assume (tso.lcm!=NULL);
+  int ng_place=IDELEMS(new_generators);
+  int i,j;
+  number coefgcd,n;
+  poly p;
+  BOOLEAN deleteP=FALSE;
+#ifdef EXPERIMENT1
+  poly syzp;
+#endif
+ 
+  assume (tso.ind1<*next_place_add);
+  assume (tso.ind2<*next_place_add);
+  assume (tso.ind1!=tso.ind2);
+  assume (tso.p1 == add_generators->m[tso.ind1]);
+  assume (tso.p2 == add_generators->m[tso.ind2]);
+  tso.p1 = add_generators->m[tso.ind1];
+  tso.p2 = add_generators->m[tso.ind2];
+  if ((tso.p1!=NULL) && (tso.p2!=NULL))
+  {
+    if (TEST_OPT_PROT)
+      Print(".");
+#ifdef USE_PROD_CRIT
+    if (pFDeg(tso.p1)+pFDeg(tso.p2)==tso.order+pFDeg(deg_soc))
+    {
+      if (TEST_OPT_PROT) Print("pc");
+      int ac=pGetComp(tso.p1);
+      assume(ac=pGetComp(tso.p2));
+      poly p1=pCopy(tso.p1);
+      poly p2=pCopy(tso.p2);
+      poly pp1,pp2,tp1,tp2;
+      poly sp1=pCopy(add_repr->m[tso.ind1]),sp2=pCopy(add_repr->m[tso.ind2]);
+      pp1 = p1;
+      pp2 = p2;
+      loop
+      {
+        assume(pp1!=NULL);
+        for(i=(int)pVariables; i; i--)
+          pSetExp(pp1,i, pGetExp(pp1,i)- pGetExp(deg_soc,i));
+        pSetComp(pp1, 0);
+        pSetm(pp1);
+        if ((pNext(pp1)!=NULL) && (pGetComp(pNext(pp1))!=ac))  break;
+        pIter(pp1);
+      }
+      loop
+      {
+        assume(pp2!=NULL);
+        for(i=(int)pVariables; i; i--)
+          pSetExp(pp2,i, pGetExp(pp2,i)- pGetExp(deg_soc,i));
+        pSetComp(pp2, 0);
+        pSetm(pp2);
+        if ((pNext(pp2)!=NULL) && (pGetComp(pNext(pp2))!=ac)) break;
+        pIter(pp2);
+      }
+      tp1 = pNext(pp1);
+      tp2 = pNext(pp2);
+      pNext(pp1) = NULL;
+      pNext(pp2) = NULL;
+      //pShift(&p1,-ac);
+      //pShift(&p2,-ac);
+      tp1 = pMult(tp1,pCopy(p2));
+      tp2 = pMult(tp2,pCopy(p1));
+      sp1 = pMult(p2,sp1);
+      sp2 = pMult(p1,sp2);
+      tso.p = pSub(tp1,tp2);
+      tso.syz = pSub(sp1,sp2);
+    }
+    else
+#endif
+    {
+      tso.p = ksOldCreateSpoly(tso.p2,tso.p1);
+      number coefgcd = nGcd(pGetCoeff(tso.p1),pGetCoeff(tso.p2),currRing);
+      assume (add_repr->m[tso.ind1]!=NULL);
+      tso.syz = pCopy(add_repr->m[tso.ind1]);
+      poly tt = pDivide(tso.lcm,tso.p1);
+      pSetComp(tt,0);
+      pSetmComp(tt);
+      pSetCoeff(tt,nDiv(pGetCoeff(tso.p1),coefgcd));
+      tso.syz = pMult_mm(tso.syz,tt);
+      pDelete(&tt);
+      coefgcd = nNeg(coefgcd);
+      assume (add_repr->m[tso.ind2]!=NULL);
+      p = pCopy(add_repr->m[tso.ind2]);
+      tt = pDivide(tso.lcm,tso.p2);
+      pSetComp(tt,0);
+      pSetmComp(tt);
+      pSetCoeff(tt,nDiv(pGetCoeff(tso.p2),coefgcd));
+      p = pMult_mm(p,tt);
+      pDelete(&tt);
+      tso.syz = pAdd(p,tso.syz);
+      nDelete(&coefgcd);
+    }
+#ifdef SHOW_PROT
+Print("reduziere Paar im Module %d mit: \n",index);
+Print("poly1: ");pWrite(tso.p1);
+Print("poly2: ");pWrite(tso.p2);
+Print("syz: ");pWrite(tso.syz);
+Print("sPoly: ");pWrite(tso.p);
+#endif
+    assume(tso.syz!=NULL);
+    kBucketInit(syzstr->syz_bucket,tso.syz,-1);
+    if (tso.p!=NULL)
+    {
+      kBucketInit(syzstr->bucket,tso.p,-1);
+      p = kBucketGetLm(syzstr->bucket);
+      j = 0;
+      loop
+      {
+        if (j>=*next_place_add) break;
+        if (pDivisibleBy(add_generators->m[j],p))
+        {
+          assume (add_repr->m[j]!=NULL);
+          sySPRedSyz_Kosz(syzstr,add_generators->m[j],add_repr->m[j],p);
+          n = kBucketPolyRed(syzstr->bucket,add_generators->m[j],
+                   pLength(add_generators->m[j]), NULL);
+          p = kBucketGetLm(syzstr->bucket);
+          if ((p==NULL) || (pGetComp(p)<=crit_comp)) break;
+          j = 0;
+        }
+        else
+          j++;
+      }
+      kBucketClear(syzstr->bucket,&tso.p,&tso.length);
+    }
+    kBucketClear(syzstr->syz_bucket,&tso.syz,&j);
+  }
+  else
+  {
+    Print("Shit happens!\n");
+  }
+#ifdef SHOW_PROT
+Print("erhalte Paar im Module %d mit: \n",index);
+Print("syz: ");pWrite(tso.syz);
+Print("sPoly: ");pWrite(tso.p);
+PrintLn();
+#endif
+  if (tso.p!=NULL)
+  {
+    if (!nIsOne(pGetCoeff(tso.p)))
+    {
+      n=nInvers(pGetCoeff(tso.p));
+      pNorm(tso.p);
+      pMult_nn(tso.syz,n);
+      nDelete(&n);
+    }
+  }
+  if ((TEST_OPT_PROT) && (tso.syz==NULL)) Print("null");
+  if ((tso.p!=NULL) && (pGetComp(tso.p)>crit_comp))
+  {
+    if (*next_place_add>=IDELEMS(add_generators))
+    {
+      pEnlargeSet(&add_generators->m,IDELEMS(add_generators),16);
+      pEnlargeSet(&add_repr->m,IDELEMS(add_repr),16);
+      *g_l = (int*)omRealloc0Size((ADDRESS)*g_l, IDELEMS(add_generators)*sizeof(int),
+                            (IDELEMS(add_generators)+16)*sizeof(int));
+      IDELEMS(add_generators) += 16;
+      IDELEMS(add_repr) += 16;
+    }
+    assume(add_repr->m[*next_place_add]==NULL);
+    add_generators->m[*next_place_add] = tso.p;
+    add_repr->m[*next_place_add] = tso.syz;
+    (*g_l)[*next_place_add] = tso.length;
+    (*next_place_add)++;
+  }
+  else
+  {
+    while ((ng_place>0) && (new_generators->m[ng_place-1]==NULL) &&
+          (new_repr->m[ng_place-1]==NULL)) ng_place--;
+    if (ng_place>=IDELEMS(new_generators))
+    {
+      pEnlargeSet(&new_generators->m,IDELEMS(new_generators),16);
+      IDELEMS(new_generators) += 16;
+      pEnlargeSet(&new_repr->m,IDELEMS(new_repr),16);
+      IDELEMS(new_repr) += 16;
+    }
+    new_generators->m[ng_place] = tso.p;
+    new_repr->m[ng_place] = tso.syz;
+  }
+  tso.p = NULL;
+  tso.syz = NULL;
+  resPairs[itso] = tso;
+  syDeletePair(&resPairs[itso]);
+}
+ 
+/*3
+* reduction of all pairs of a fixed degree of a fixed module
+*/
+static BOOLEAN reducePairsHIndex(SSet resPairs,int l_pairs,syStrategy syzstr,
+       int index,ideal add_generators,ideal add_repr,ideal new_generators,
+       ideal new_repr,int crit_comp,int * red_deg,int * next_place_add,int **g_l,
+       resolvente totake)
+{
+  if (resPairs[0].lcm==NULL) return FALSE;
+  int i=0,j;
+  poly deg_soc;
+ 
+  if (TEST_OPT_PROT)
+    Print("(%d,%d)",index,resPairs[0].order);
+  while ((i<l_pairs) && (resPairs[i].order==*red_deg))
+  {
+    assume(totake[index-1]!=NULL);
+    assume(pGetComp(resPairs[i].p1)<=IDELEMS(totake[index-1]));
+    assume(totake[index-1]->m[pGetComp(resPairs[i].p1)-1]!=NULL);
+    deg_soc = totake[index-1]->m[pGetComp(resPairs[i].p1)-1];
+    redOnePairHIndex(resPairs,i,crit_comp,syzstr,index, add_generators,add_repr,
+                     new_generators, new_repr,next_place_add,g_l,deg_soc);
+    i++;
+  }
+  syCompactifyPairSet(resPairs,l_pairs,0);
+  if (resPairs[0].lcm==NULL)  //there are no pairs left and no new_gens
+    return FALSE;
+  else
+    *red_deg = resPairs[0].order;
+  return TRUE;
+}
+ 
+/*3
+* we proceed the generators of the next module;
+* they are stored in add_generators and add_repr;
+* if the normal form of a new genrators w.r.t. add_generators has 
+* pGetComp<crit_comp it is skipped from the reduction;
+* new_generators and new_repr (which are empty) stores the result of the 
+* reduction which is normalized afterwards
+*/
+static void procedeNextGenerators(ideal temp_generators,ideal temp_repr,
+      ideal new_generators, ideal new_repr, ideal add_generators,
+      ideal add_repr, syStrategy syzstr,int index, int crit_comp,
+      resolvente totake)
+{
+  int i=0,j,next_new_el;
+  int idel_temp=IDELEMS(temp_generators);
+  int next_place_add;
+  int p_length,red_deg,l_pairs=IDELEMS(add_generators);
+  poly next_p;
+  int * gen_length=(int*)omAlloc0(IDELEMS(add_generators)*sizeof(int));
+  int * secgen_length=(int*)omAlloc0(IDELEMS(syzstr->res[index])*sizeof(int));
+  BOOLEAN pairs_left;
+  SSet resPairs=(SSet)omAlloc0(l_pairs*sizeof(SObject));
+ 
+  for (j=IDELEMS(syzstr->res[index])-1;j>=0;j--)
+  {
+    if (syzstr->res[index]->m[j]!=NULL)
+      secgen_length[j] = pLength(syzstr->res[index]->m[j]);
+  }
+  assume(idIs0(new_generators));
+  next_place_add = IDELEMS(add_generators);
+  while ((next_place_add>0) && (add_generators->m[next_place_add-1]==NULL))
+    next_place_add--;
+  int next_deg = pFDeg(temp_generators->m[i]);
+  next_new_el = next_place_add;
+/*--- loop about all all elements-----------------------------------*/
+  while ((i<idel_temp) && (temp_generators->m[i]!=NULL))
+  {
+/*--- separates elements of equal degree----------------------------*/
+#ifdef USE_REGULARITY
+    if (syzstr->regularity>0)
+    {
+      if (next_deg >= syzstr->regularity+index) 
+      {
+        while ((i<idel_temp) && (temp_generators->m[i]!=NULL))
+        {
+          pDelete(&temp_generators->m[i]);
+          i++;
+        }
+        break;
+      }
+    }
+#endif
+    while ((i<idel_temp) && (pFDeg(temp_generators->m[i])==next_deg))
+    {
+      next_p = temp_generators->m[i];
+      temp_generators->m[i] = NULL;
+      next_p = normalize(next_p,add_generators,syzstr,gen_length,&p_length,
+                crit_comp);
+      if (next_p!=NULL)
+      {
+        if (pGetComp(next_p)<=crit_comp)
+        {
+          pDelete(&next_p);
+          //if (TEST_OPT_PROT) Print("u(%d)",index);
+        }
+        else
+        {
+          next_p = syRedTailSyz(next_p,add_generators,syzstr->res[index],crit_comp,syzstr,
+            gen_length,secgen_length,&p_length);
+          if (!nIsOne(pGetCoeff(next_p)))
+            pNorm(next_p);
+          if (next_place_add>=IDELEMS(add_generators))
+          {
+            pEnlargeSet(&add_generators->m,IDELEMS(add_generators),16);
+            pEnlargeSet(&add_repr->m,IDELEMS(add_repr),16);
+            gen_length = (int*)omRealloc0Size((ADDRESS)gen_length, IDELEMS(add_generators)*sizeof(int), 
+                                        (IDELEMS(add_generators)+16)*sizeof(int));
+            IDELEMS(add_generators) += 16;
+            IDELEMS(add_repr) += 16;
+          }
+          add_generators->m[next_place_add] = next_p;
+          if (totake[index]==NULL)
+            totake[index] = idInit(16,new_generators->rank);
+          if ((*syzstr->Tl)[index]==IDELEMS(totake[index]))
+          {
+            pEnlargeSet(&totake[index]->m,IDELEMS(totake[index]),
+                        (*syzstr->Tl)[index]+16-IDELEMS(totake[index]));
+            for (j=IDELEMS(totake[index]);j<(*syzstr->Tl)[index]+16;j++)
+              totake[index]->m[j] = NULL;
+            IDELEMS(totake[index]) = (*syzstr->Tl)[index]+16;
+          }
+#ifdef FULL_TOTAKE
+          totake[index]->m[(*syzstr->Tl)[index]] = pCopy(next_p);
+#else
+          totake[index]->m[(*syzstr->Tl)[index]] = pHead(next_p);
+#endif
+          assume(add_repr->m[next_place_add]==NULL);
+#ifdef WITH_SCHREYER_ORD
+          add_repr->m[next_place_add] = pHead(add_generators->m[next_place_add]);
+#else
+          add_repr->m[next_place_add] = pOne();
+#endif
+          ((*syzstr->Tl)[index])++;
+          pSetComp(add_repr->m[next_place_add],(*syzstr->Tl)[index]);
+          pSetmComp(add_repr->m[next_place_add]);
+          gen_length[next_place_add] = p_length;
+          next_place_add++;
+        }
+      }
+      i++;
+    }                        //end inner loop
+    red_deg = next_deg;
+    if (i<idel_temp)
+      next_deg = pFDeg(temp_generators->m[i]);
+    else
+      next_deg = -1;
+    if ((next_place_add>next_new_el) || (next_deg<0))  //there are new generators or pairs
+    {
+/*-reducing and generating pairs untill the degree of the next generators-*/
+      pairs_left = TRUE;
+      while (pairs_left && ((next_deg<0) || (red_deg<= next_deg)))
+      {
+        updatePairsHIndex(&resPairs,&l_pairs,syzstr,index,add_generators,
+          add_repr,new_generators,new_repr,crit_comp,&next_new_el);
+        pairs_left = reducePairsHIndex(resPairs,l_pairs,syzstr,index,add_generators,
+           add_repr,new_generators,new_repr,crit_comp,&red_deg,&next_place_add,&gen_length,
+           totake);
+      }
+    }
+  }
+  omFreeSize((SSet)resPairs,l_pairs*sizeof(SObject));
+  omFreeSize((ADDRESS)gen_length,IDELEMS(add_generators)*sizeof(int));
+  omFreeSize((ADDRESS)secgen_length,IDELEMS(syzstr->res[index])*sizeof(int));
+}
+ 
+/*3
+* normalizes the part of the next reduction lying within the block
+* of former generators (old_generators);
+*/
+static ideal normalizeOldPart(ideal new_generators,ideal new_repr,
+                      syStrategy syzstr,int index,int crit_comp)
+{
+  ideal old_generators= syzstr->res[index];
+  ideal old_repr= syzstr->orderedRes[index];
+  int i,j=0,ii=IDELEMS(old_generators)-1,dummy;
+  poly p;
+  number n;
+  int * g_l=(int*)omAlloc0(IDELEMS(old_generators)*sizeof(int));
+ 
+  for (i=0;i<IDELEMS(old_generators);i++)
+  {
+    if (old_generators->m[i]!=NULL)
+    {
+      g_l[i] = pLength(old_generators->m[i]);
+    }
+  }
+  for (i=IDELEMS(new_generators)-1;i>=0;i--) 
+  {
+    if (new_generators->m[i]!=NULL)
+    {
+      kBucketInit(syzstr->bucket,new_generators->m[i],
+                   pLength(new_generators->m[i]));
+      kBucketInit(syzstr->syz_bucket,new_repr->m[i],
+                   pLength(new_repr->m[i]));
+      p = kBucketGetLm(syzstr->bucket);
+      loop
+      {
+        if ((j>=ii) || (p==NULL)) break;
+        if ((old_generators->m[j]!=NULL) && 
+            (pDivisibleBy(old_generators->m[j],p)))
+        {
+          sySPRedSyz_Kosz(syzstr,old_generators->m[j],old_repr->m[j],p);
+          n = kBucketPolyRed(syzstr->bucket,old_generators->m[j], g_l[j], NULL);
+          nDelete(&n);
+          p = kBucketGetLm(syzstr->bucket);
+          j = 0;
+        }
+        else
+          j++;
+      }
+      assume (p==NULL);
+      kBucketClear(syzstr->bucket,&new_generators->m[i],&dummy);
+      kBucketClear(syzstr->syz_bucket,&new_repr->m[i],&dummy);
+    }
+  }
+  ideal result=idInit(IDELEMS(new_repr),new_repr->rank);
+  for (j=IDELEMS(new_repr)-1;j>=0;j--)
+  {
+    result->m[j] = new_repr->m[j];
+    if ((result->m[j]!=NULL) && (!nIsOne(pGetCoeff(result->m[j]))))
+      pNorm(result->m[j]);
+    new_repr->m[j] = NULL;
+  }
+  omFreeSize((ADDRESS)g_l,IDELEMS(old_generators)*sizeof(int));
+  return result;
+}
+ 
+/*3
+* constructs the new subresolution for a nonregular extension
+*/
+static ideal kosz_ext(ideal new_generators,ideal new_repr,syStrategy syzstr,
+                      int index,int next_comp,resolvente totake)
+{
+  ideal temp_generators =idInit(IDELEMS(new_generators),new_generators->rank);
+  ideal temp_repr=idInit(IDELEMS(new_repr),new_repr->rank);
+  ideal add_generators =idInit(IDELEMS(new_generators),new_generators->rank);
+  ideal add_repr=idInit(IDELEMS(new_repr),new_repr->rank);
+  int min_deg=-1;
+  int j,jj,k,deg_p,idel_temp=IDELEMS(temp_generators);
+  poly p;
+/*--reorder w.r.t. the degree----------------------------------------*/
+  for (j=IDELEMS(new_generators)-1;j>=0;j--)
+  {
+    if (new_generators->m[j]!=NULL)
+    {
+      p = new_generators->m[j];
+      new_generators->m[j] = NULL;
+      deg_p = pFDeg(p);
+      if (min_deg<0)
+      {
+        min_deg = deg_p;
+      }
+      else
+      {
+        if (deg_p<min_deg) min_deg = deg_p;
+      }
+      k = 0;
+      while ((k<idel_temp) && (temp_generators->m[k]!=NULL) &&
+             (pFDeg(temp_generators->m[k])<=deg_p)) k++;
+      for (jj=idel_temp-1;jj>k;jj--)
+      {
+        temp_generators->m[jj] = temp_generators->m[jj-1];
+      }
+      temp_generators->m[k] = p;
+    }
+  }
+/*--- computing the standard basis in the resolution of the extension -*/
+  procedeNextGenerators(temp_generators,temp_repr,new_generators,new_repr,
+    add_generators,add_repr,syzstr,index,next_comp,totake);
+  j = IDELEMS(syzstr->res[index]);
+  while ((j>0) && (syzstr->res[index]->m[j-1]==NULL)) j--;
+  jj = IDELEMS(add_generators);
+  while ((jj>0) && (add_generators->m[jj-1]==NULL)) jj--;
+  if (j+jj>=IDELEMS(syzstr->res[index]))
+  {
+    pEnlargeSet(&syzstr->res[index]->m,IDELEMS(syzstr->res[index]),
+                j+jj+1-IDELEMS(syzstr->res[index]));
+    IDELEMS(syzstr->res[index]) = j+jj+1;
+    pEnlargeSet(&syzstr->orderedRes[index]->m,IDELEMS(syzstr->orderedRes[index]),
+                j+jj+1-IDELEMS(syzstr->orderedRes[index]));
+    IDELEMS(syzstr->orderedRes[index]) = j+jj+1;
+  }
+  for (k=0;k<jj;k++)
+  {
+    syzstr->res[index]->m[j+k] = add_generators->m[k];
+    syzstr->orderedRes[index]->m[j+k] = add_repr->m[k];
+    add_generators->m[k] = NULL;
+    add_repr->m[k] = NULL;
+  }
+  assume(idIs0(add_generators));
+  assume(idIs0(add_repr));
+  idDelete(&add_generators);
+  idDelete(&add_repr);
+  idDelete(&temp_generators);
+  idDelete(&temp_repr);
+/*--- normalizing the rest to get the syzygies ------------------------*/
+  return normalizeOldPart(new_generators,new_repr,syzstr,index,next_comp);
+}
+ 
+/*
+* this procedure assumes that the first order is C !!!
+* INPUT: old_generators - the generators of the actual module
+*                         computed so far (they are mixed vectors)
+*        old_repr       - the representations of the old generators
+*        new_generators - generators coming from reductions below,
+*                         they must have leading terms in new components
+*                         (they live only in the module part)
+*  (*syzstr->Tl)[index] - the last used component in the syzygy
+* OUTPUT: old_generators is updated
+*         new_generators is empty
+*         the return value is a set of new generators for the syzygies,
+*/
+static ideal syAppendSyz(ideal new_generators, syStrategy syzstr,int index,int crit_comp,
+                         resolvente totake)
+{
+  int i,j,newIdeal;
+  intvec * w;
+  poly p;
+  ideal result;
+  int rk_new_gens = idRankFreeModule(new_generators);
+  if (syzstr->res[index]==NULL)
+  {
+    syzstr->res[index] = idInit(1,si_max(rk_new_gens,1));
+    syzstr->orderedRes[index] = idInit(1,si_max(rk_new_gens,1));
+  }
+  int ng_idel=IDELEMS(new_generators);
+  ideal new_repr =idInit(ng_idel, crit_comp+ng_idel);
+ 
+  if (index==0)
+  {
+    //int * og_l=(int*)omAlloc0(IDELEMS(syzstr->res[0])*sizeof(int));
+    //for (i=IDELEMS(syzstr->res[0])-1;i>=0;i--)
+    //{
+      //if (syzstr->res[0]->m[i]!=NULL)
+        //og_l[i] = pLength(syzstr->res[0]->m[i]);
+    //}
+    for (i=0;i<ng_idel;i++)
+    {
+      if (new_generators->m[i]!=NULL)
+      {
+        //int ng_l=pLength(new_generators->m[i]);
+        //new_generators->m[i] = syRedTailSyz(new_generators->m[i],syzstr->res[0],NULL,0,syzstr,
+            //og_l,NULL,&ng_l);
+        if (totake[index]==NULL)
+          totake[index] = idInit(16,new_generators->rank);
+        if ((*syzstr->Tl)[index]>=IDELEMS(totake[index]))
+        {
+          pEnlargeSet(&totake[index]->m,IDELEMS(totake[index]),
+                      (*syzstr->Tl)[index]+16-IDELEMS(totake[index]));
+          for (j=IDELEMS(totake[index]);j<(*syzstr->Tl)[index]+16;j++)
+            totake[index]->m[j] = NULL;
+          IDELEMS(totake[index]) = (*syzstr->Tl)[index]+16;
+        }
+#ifdef FULL_TOTAKE
+        totake[index]->m[(*syzstr->Tl)[index]] = pCopy(new_generators->m[i]);
+#else
+        totake[index]->m[(*syzstr->Tl)[index]] = pHead(new_generators->m[i]);
+#endif
+#ifdef WITH_SCHREYER_ORD
+        new_repr->m[i] = pHead(new_generators->m[i]);
+#else
+        new_repr->m[i] = pOne();
+#endif
+        ((*syzstr->Tl)[index])++;
+        pSetComp(new_repr->m[i],(*syzstr->Tl)[index]);
+        pSetmComp(new_repr->m[i]);
+      }
+    }
+    //omFreeSize((ADDRESS)og_l,IDELEMS(syzstr->res[0])*sizeof(int));
+#ifdef SHOW_PROT
+Print("Add new generators: \n");
+idPrint(new_generators);
+Print("with representaions: \n");
+idPrint(new_repr);
+#endif
+    result = kosz_std(new_generators,new_repr,syzstr,index,crit_comp);
+  }
+  else
+  {
+    result = kosz_ext(new_generators,new_repr,syzstr,index,crit_comp,totake);
+  }
+  idSkipZeroes(result);
+  assume(idIs0(new_repr));
+  idDelete(&new_repr);
+  return result;
+}
+ 
+/*
+* main call of the extended Koszul-resolution
+*/
+syStrategy syKosz(ideal arg,int * length)
+{
+  int i,j,jj,k=0,index=0,rk_arg,actual_syzcomp,next_syz=0;
+  int crit_comp,t_comp,next_deg,old_tl;
+  ideal temp=NULL,old_ideal,old_repr;
+  ring origR = currRing,actR;
+  poly p,next_gen;
+  tHomog hom=isNotHomog;
+  BOOLEAN isRegular;
+ 
+  discard_pairs = 0;
+  short_pairs = 0;
+  if (idIs0(arg)) return NULL;
+  rk_arg = idRankFreeModule(arg);
+  syStrategy syzstr=(syStrategy)omAlloc0(sizeof(ssyStrategy));
+/*--- changes to a Cdp-ring ----------------------------*/
+  syzstr->syRing = rCurrRingAssure_C_dp();
+/*--- initializes the data structures---------------*/
+  syzstr->length = *length = pVariables+2;
+  syzstr->regularity = -1;
+  if (origR!=syzstr->syRing)
+    temp = idrCopyR(arg,origR);
+  else
+    temp = idCopy(arg);
+  if (rk_arg==0)
+  {
+    for (j=0;j<IDELEMS(temp);j++)
+    {
+      if (temp->m[j]!=NULL)
+        pShift(&temp->m[j],1);
+    }
+  }
+  idSkipZeroes(temp);
+#ifdef WITH_SORT
+  if (temp->m[0]!=NULL)
+  {
+    int maxdeg=pFDeg(temp->m[IDELEMS(temp)-1]),md;
+    ideal temp1=idInit(IDELEMS(temp),temp->rank);
+    for (j=IDELEMS(temp)-2;j>=0;j--)
+    {
+      jj = pFDeg(temp->m[j]);
+      if (jj>maxdeg) maxdeg = jj;
+    }
+    while (!idIs0(temp))
+    {
+      md = maxdeg;
+      for (j=IDELEMS(temp)-1;j>=0;j--)
+      {
+        if (temp->m[j]!=NULL)
+        {
+          jj = pFDeg(temp->m[j]);
+          if (jj<md) md = jj;
+        }
+      }
+      for (j=0;j<IDELEMS(temp);j++)
+      {
+        if ((temp->m[j]!=NULL) && (pFDeg(temp->m[j])==md))
+        {
+          temp1->m[k] = temp->m[j];
+          temp->m[j] = NULL;
+          k++;
+        }
+      }
+    }
+    idDelete(&temp);
+    temp = temp1;
+    temp1 = NULL;
+  }
+#endif
+#ifdef USE_REGULARITY
+  int last_generator=IDELEMS(temp)-1;
+  while ((last_generator>=0) && (temp->m[last_generator]==NULL))
+    last_generator--;
+#endif
+  syzstr->res = (resolvente)omAlloc0((*length+1)*sizeof(ideal));
+  syzstr->orderedRes = (resolvente)omAlloc0((*length+1)*sizeof(ideal));
+  resolvente totake=(resolvente)omAlloc0((*length+1)*sizeof(ideal));
+  syzstr->Tl = new intvec(*length+1);
+  syzstr->bucket = kBucketCreate();
+  syzstr->syz_bucket = kBucketCreate();
+  ideal new_generators=idInit(1,si_max(rk_arg,1));
+  ideal temp_gens,old_std;
+  syzstr->res[0] = idInit(1,1);
+  if (rk_arg>1) syzstr->res[0]->rank = rk_arg;
+  syzstr->orderedRes[0] = idInit(1,1);
+/*--- computes the resolution ----------------------*/
+  i = 0;
+  while (i<IDELEMS(temp))
+  {
+    if (temp->m[i]!=NULL)
+    {
+      new_generators->m[0] = kNF(syzstr->res[0],currQuotient,temp->m[i]);
+      if (!nIsOne(pGetCoeff(new_generators->m[0])))
+        pNorm(new_generators->m[0]);
+      next_deg = pFDeg(new_generators->m[0]);
+      next_gen = pCopy(new_generators->m[0]);
+    }
+    if (!idIs0(new_generators))
+    {
+      index = 0;
+      while (index<=*length)
+      {
+        if (index==0)
+        {
+          old_ideal = idCopy(syzstr->res[0]);
+          old_repr = idCopy(syzstr->orderedRes[0]);
+          old_tl = (*syzstr->Tl)[0];
+          old_std = idHead(syzstr->res[0]);
+        }
+        t_comp = (*syzstr->Tl)[index];
+        if (index==0) crit_comp = t_comp;
+        temp_gens = syAppendSyz(new_generators,syzstr, index,crit_comp,totake);
+        crit_comp = t_comp;
+        if (index==0)
+        {
+          isRegular = syIsRegular(old_std,syzstr->res[0],next_deg);
+#ifndef ONLY_STD
+          if (isRegular)
+            syCreateRegularExtension(syzstr,old_ideal,old_repr,old_tl,next_gen,
+                                     totake);
+#ifdef USE_REGULARITY
+        if ((index==0) && (!isRegular) && (i==last_generator))
+        {
+/*----------- we are computing the regularity -----------------------*/
+          ideal initial=idHead(syzstr->res[0]);
+          int len=0,reg=0;
+          intvec *w=NULL;
+          ring dp_C_ring = rCurrRingAssure_dp_C();
+          initial = idrMoveR_NoSort(initial, syzstr->syRing);
+          resolvente res = sySchreyerResolvente(initial,-1,&len,TRUE, TRUE);
+          intvec * dummy = syBetti(res,len,&reg, w);
+          syzstr->regularity = reg+2;
+          delete dummy;
+          delete w;
+          for (j=0;j<len;j++)
+          {
+            if (res[j]!=NULL) idDelete(&(res[j]));
+          }
+          omFreeSize((ADDRESS)res,len*sizeof(ideal));
+          idDelete(&initial);
+          rChangeCurrRing(syzstr->syRing);
+          rKill(dp_C_ring);
+        }
+#endif
+#endif
+          idDelete(&old_ideal);
+          idDelete(&old_repr);
+          idDelete(&old_std);
+          if (TEST_OPT_PROT)
+          {
+            if (isRegular)
+              Print("\n regular\n");
+            else
+              Print("\n not regular\n");
+          }
+          if (next_gen!=NULL)
+            pDelete(&next_gen);
+          if (isRegular)
+          {
+            idDelete(&temp_gens);
+            break;
+          }
+        }
+        idDelete(&new_generators);
+        new_generators = temp_gens;
+#ifdef ONLY_STD
+        break; 
+#endif
+        if (idIs0(new_generators)) break;
+        index++;
+      }
+      if (!idIs0(new_generators))
+      {
+        for (j=0;j<IDELEMS(new_generators);j++)
+        {
+          if (new_generators->m[j]!=NULL)
+          {
+            pDelete(&new_generators->m[j]);
+            new_generators->m[j] = NULL;
+          }
+        }
+      }
+    }
+    i++;
+  }
+  if (idIs0(new_generators) && new_generators!=NULL) idDelete(&new_generators);
+  if (temp!=NULL) idDelete(&temp);
+  kBucketDestroy(&(syzstr->bucket));
+  kBucketDestroy(&(syzstr->syz_bucket));
+  index = 0;
+  syzstr->fullres = syzstr->res;
+  syzstr->res = NULL;
+  index = 0;
+  while ((index<=*length) && (syzstr->fullres[index]!=NULL))
+  {
+#ifdef SHOW_RESULT
+    Print("The %d-th syzygy-module is now:\n",index);
+    ideal ttt=idHead(syzstr->fullres[index]);
+    idShow(ttt);
+    idDelete(&ttt);
+    //if (index>0)
+    //{
+      //Print("The related module is: \n");
+      //idPrint(totake[index-1]);
+    //}
+    //Print("The %d-th module of the minimal resolution is:\n",index);
+    if (!idIs0(totake[index]))
+      idShow(totake[index]);
+    //Print("with standard basis:\n");
+    //idPrint(syzstr->fullres[index]);
+    //if ((index<*length) && (totake[index+1]!=NULL))
+    //{
+      //Print("The %d-th syzygy-module is now:\n",index+1);
+      //idPrint(totake[index+1]);
+      //matrix m1=idModule2Matrix(totake[index]);
+      //matrix m2=idModule2Matrix(totake[index+1]);
+      //matrix m3=mpMult(m1,m2);
+      //idPrint((ideal)m3);
+    //}
+#endif
+    if (!idIs0(totake[index]))
+    {
+      for(i=0;i<IDELEMS(totake[index]);i++)
+      {
+        if (totake[index]->m[i]!=NULL)
+        {
+          j=0;
+          while ((j<IDELEMS(syzstr->fullres[index])) &&
+            ((syzstr->fullres[index]->m[j]==NULL) ||
+            (!pLmEqual(syzstr->fullres[index]->m[j],totake[index]->m[i])))) j++;
+          if (j<IDELEMS(syzstr->fullres[index]))
+          {
+            pDelete(&totake[index]->m[i]);
+            totake[index]->m[i] = syzstr->fullres[index]->m[j];
+            syzstr->fullres[index]->m[j] = NULL;
+          }
+          else
+          {
+            Print("Da ist was faul!!!\n");
+            Print("Aber: Regularitaet %d, Grad %d\n",syzstr->regularity,pFDeg(totake[index]->m[i]));
+          }
+        }
+      }
+      idDelete(&syzstr->fullres[index]);
+      syzstr->fullres[index] = totake[index];
+    }
+#ifdef SHOW_RESULT
+    idShow(syzstr->fullres[index]);
+#endif
+    index++;
+  }
+  syReorder_Kosz(syzstr);
+  index = 0;
+  while ((index<=*length) && (syzstr->orderedRes[index]!=NULL))
+  {
+    idDelete(&(syzstr->orderedRes[index]));
+    index++;
+  }
+  if (origR!=syzstr->syRing)
+  {
+    rChangeCurrRing(origR);
+    index = 0;
+    while ((index<=*length) && (syzstr->fullres[index]!=NULL))
+    {
+      syzstr->fullres[index] = idrMoveR(syzstr->fullres[index],syzstr->syRing);
+      index++;
+    }
+  }
+  delete syzstr->Tl;
+  syzstr->Tl = NULL;
+  rKill(syzstr->syRing);
+  syzstr->syRing = NULL;
+  omFreeSize((ADDRESS)totake,(*length+1)*sizeof(ideal));
+  omFreeSize((ADDRESS)syzstr->orderedRes,(*length+1)*sizeof(ideal));
+//Print("Pairs to discard: %d\n",discard_pairs);
+//Print("Pairs shorter reduced: %d\n",short_pairs);
+//discard_pairs = 0;
+//short_pairs = 0;
+  return syzstr;
+}
+
Index: kernel/testgh
===================================================================
--- kernel/testgh	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/testgh	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,19 @@
+#!/bin/sh
+if [ -f grammar.hh ]
+then
+  mv grammar.hh grammar.cc.h
+fi
+if [ -f grammar.h ]
+then
+  if diff grammar.cc.h grammar.h >/dev/null
+  then
+    echo grammar.h was okay
+    /bin/rm grammar.cc.h
+  else
+    echo generating new grammar.h
+    mv grammar.cc.h grammar.h
+  fi
+else
+  echo generating grammar.h
+  mv grammar.cc.h grammar.h
+fi
Index: kernel/tesths.cc
===================================================================
--- kernel/tesths.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/tesths.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,249 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: tesths.cc,v 1.1.1.1 2003-10-06 12:16:04 Singular Exp $ */
+
+/*
+* ABSTRACT - initialize SINGULARs components, run Script and start SHELL
+*/
+
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <time.h>
+#include <errno.h>
+#include "mod2.h"
+#include "tok.h"
+#include "ipshell.h"
+#include "sing_dld.h"
+#include "febase.h"
+#include "cntrlc.h"
+#include "omalloc.h"
+#include "silink.h"
+#include "ipid.h"
+#include "timer.h"
+#include "sdb.h"
+#include "fegetopt.h"
+#include "feOpt.h"
+#include "distrib.h"
+#include "version.h"
+#include "slInit.h"
+
+#ifdef HAVE_FACTORY
+#define SI_DONT_HAVE_GLOBAL_VARS
+#include <factory.h>
+#endif
+
+char *singular_date=__DATE__ " " __TIME__;
+
+/*0 implementation*/
+int main(          /* main entry to Singular */
+    int argc,      /* number of parameter */
+    char** argv)   /* parameter array */
+{
+#ifdef HAVE_FACTORY
+  //On(SW_USE_NTL);
+#endif
+
+#ifdef INIT_BUG
+  jjInitTab1();
+#endif
+#ifdef GENTABLE
+  extern void ttGen1();
+  extern void ttGen2();
+  #ifndef __MWERKS__
+    extern void mpsr_ttGen(); // For initialization of (CMD, MP_COP) tables
+    mpsr_ttGen();
+  #endif
+  ttGen1();
+  ttGen2();
+#else
+  // Don't worry: ifdef OM_NDEBUG, then all these calls are undef'ed
+  omInitRet_2_Info(argv[0]);
+  omInitGetBackTrace();
+
+  /* initialize components */
+  siRandomStart=inits();
+  feOptSpec[FE_OPT_RANDOM].value = (void*) siRandomStart;
+  int optc, option_index;
+  char* errormsg;
+
+  // do this first, because -v might print version path
+  feInitResources(argv[0]);
+
+  // parse command line options
+  while((optc = fe_getopt_long(argc, argv,
+                               SHORT_OPTS_STRING, feOptSpec, &option_index))
+        != EOF)
+  {
+    if (optc == '?' || optc == 0)
+    {
+      fprintf(stderr, "Use '%s --help' for a complete list of options\n", feArgv0);
+      exit(1);
+    }
+
+    if (optc != LONG_OPTION_RETURN)
+      option_index = feGetOptIndex(optc);
+
+    assume(option_index >= 0 && option_index < (int) FE_OPT_UNDEF);
+
+    if (fe_optarg == NULL &&
+        (feOptSpec[option_index].type == feOptBool ||
+         feOptSpec[option_index].has_arg == optional_argument))
+      errormsg = feSetOptValue((feOptIndex) option_index, (int) 1);
+    else
+      errormsg = feSetOptValue((feOptIndex) option_index, fe_optarg);
+
+    if (errormsg)
+    {
+      if (fe_optarg == NULL)
+        fprintf(stderr, "Error: Option '--%s' %s\n",
+               feOptSpec[option_index].name, errormsg);
+      else
+        fprintf(stderr, "Error: Option '--%s=%s' %s\n",
+               feOptSpec[option_index].name, fe_optarg, errormsg);
+      fprintf(stderr, "Use '%s --help' for a complete list of options\n", feArgv0);
+      exit(1);
+    }
+    if (optc == 'h') exit(0);
+  }
+
+  /* say hello */
+  {
+#ifdef HAVE_NS
+    basePack=(package)omAlloc0(sizeof(*basePack));
+    currPack=basePack;
+    idhdl h;
+    h=enterid("Top", 0, PACKAGE_CMD, &IDROOT, TRUE);
+    IDPACKAGE(h)->language = LANG_TOP;
+    IDPACKAGE(h)=basePack;
+    currPackHdl=h;
+    basePackHdl=h;
+#endif /* HAVE_NS */
+  }
+  if (BVERBOSE(0))
+  {
+    (printf)(
+#ifdef HAVE_PLURAL
+"                     SINGULAR::PLURAL                      "
+#else
+"                     SINGULAR                             /"
+#endif
+#ifndef MAKE_DISTRIBUTION
+"  Development"
+#endif
+"\n"
+#ifdef HAVE_PLURAL
+" A Computer Algebra System for Polynomial Computations    /   version %s\n"
+"        in Noncommutative Polynomial Algebras            /\n"
+"                                                       0<\n"
+"     by: G.-M. Greuel, V. Levandovskyy, H. Schoenemann   \\   %s\n"
+"FB Mathematik der Universitaet, D-67653 Kaiserslautern    \\\n"
+#else 
+" A Computer Algebra System for Polynomial Computations   /   version %s\n"
+"                                                       0<\n"
+"     by: G.-M. Greuel, G. Pfister, H. Schoenemann        \\   %s\n"
+"FB Mathematik der Universitaet, D-67653 Kaiserslautern    \\\n"
+#endif
+, S_VERSION1,S_VERSION2);
+  }
+  else
+  {
+#ifdef HAVE_SDB
+    sdb_flags = 0;
+#endif
+#ifdef __MWERKS__
+    memcpy(stderr,stdout,sizeof(FILE));
+#else
+    dup2(1,2);
+#endif
+  }
+  slStandardInit();
+  dlInit(feArgv0);
+  myynest=0;
+  if (! feOptValue(FE_OPT_NO_STDLIB))
+  {
+    int vv=verbose;
+    verbose &= ~Sy_bit(V_LOAD_LIB);
+    iiLibCmd(omStrDup("standard.lib"), TRUE);
+    verbose=vv;
+  }
+  errorreported = 0;
+
+  // and again, ifdef OM_NDEBUG this call is undef'ed
+  // otherwise, it marks all memory allocated so far as static
+  // i.e. as memory which is not mention on omPrintUsedAddr:
+  //omMarkMemoryAsStatic();
+
+  setjmp(si_start_jmpbuf);
+
+  // Now, put things on the stack of stuff to do
+  // Last thing to do is to execute given scripts
+  if (fe_optind < argc)
+  {
+    int i = argc - 1;
+    FILE *fd;
+    while (i >= fe_optind)
+    {
+      if ((fd = feFopen(argv[i], "r")) == NULL)
+      {
+        Warn("Can not open %s", argv[i]);
+      }
+      else
+      {
+        fclose(fd);
+        newFile(argv[i]);
+      }
+      i--;
+    }
+  }
+  else
+  {
+    currentVoice=feInitStdin(NULL);
+  }
+
+  // before scripts, we execute -c, if it was given
+  if (feOptValue(FE_OPT_EXECUTE) != NULL)
+    newBuffer(omStrDup((char*) feOptValue(FE_OPT_EXECUTE)), BT_execute);
+
+  // first thing, however, is to load .singularrc from Singularpath
+  // and cwd/$HOME (in that order).
+  if (! feOptValue(FE_OPT_NO_RC))
+  {
+    char buf[MAXPATHLEN];
+    FILE * rc = feFopen("." DIR_SEPP ".singularrc", "r", buf);
+    if (rc == NULL) rc = feFopen("~" DIR_SEPP ".singularrc", "r", buf);
+    if (rc == NULL) rc = feFopen(".singularrc", "r", buf);
+
+    if (rc != NULL)
+    {
+      if (BVERBOSE(V_LOAD_LIB))
+        Print("// ** executing %s\n", buf);
+      fclose(rc);
+      newFile(buf);
+    }
+  }
+
+  /* start shell */
+  if (fe_fgets_stdin==fe_fgets_dummy)
+  {
+#ifdef HAVE_MPSR
+    BatchDoProc batch_do = slInitMPBatchDo();
+    if (batch_do != NULL)
+      return (*batch_do)((char*) feOptValue(FE_OPT_MPPORT),
+                         (char*) feOptValue(FE_OPT_MPHOST));
+    else
+      return 1;
+#else
+    assume(0);
+#endif
+  }
+  setjmp(si_start_jmpbuf);
+  yyparse();
+  m2_end(0);
+#endif
+  return 0;
+}
+
Index: kernel/tgb.cc
===================================================================
--- kernel/tgb.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/tgb.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,2960 @@
+
+// #define OM_CHECK 3
+// #define OM_TRACK 5
+// #define OM_KEEP  1
+// TODO: 
+//       deg -> poly_crit
+//       multiple rings
+//       shorten_tails und dessen Aufrufe pruefen wlength!!!
+//       calculating with formal sums
+//       try to create spolys as formal sums
+
+#include "tgb.h"
+
+#define LEN_VAR1
+#define degbound(p) assume(pTotaldegree(p)<10)
+#define inDebug(p) assume((debug_Ideal==NULL)||(kNF(debug_Ideal,NULL,p,0,0)==0))
+#ifdef LEN_VAR1
+// erste Variante: Laenge: Anzahl der Monome
+int pSLength(poly p, int l) {
+  return l; }
+int kSBucketLength(kBucket* bucket) {return bucket_guess(bucket);}
+#endif
+
+#ifdef LEN_VAR2
+// 2. Variante: Laenge: Platz fuer die Koeff.
+int pSLength(poly p,int l)
+{
+  int s=0;
+  while (p!=NULL) { s+=nSize(pGetCoeff(p));pIter(p); }
+  return s;
+}
+int kSBucketLength(kBucket* b)
+{
+  int s=0;
+  int i;
+  for (i=MAX_BUCKET;i>=0;i--)
+  {
+    s+=pSLength(b->buckets[i],0);
+  }
+  return s;
+}
+#endif
+
+#ifdef LEN_VAR3
+// 3.Variante: Laenge: Platz fuer Leitk * Monomanzahl
+int pSLength(poly p,int l)
+{
+  int c=nSize(pGetCoeff(p));
+  return c*l /*pLength(p)*/;
+}
+int kSBucketLength(kBucket* b)
+{
+  int s=0;
+  int c=nSize(pGetCoeff(kBucketGetLm(b)))+1;
+  int i;
+  for (i=MAX_BUCKET;i>0;i--)
+  {
+    s+=b->buckets_length[i] /*pLength(b->buckets[i])*/;
+  }
+  return s*c;
+}
+#endif
+
+#ifdef LEN_VAR4
+// 4.Variante: Laenge: Platz fuer Leitk * (1+Platz fuer andere Koeff.)
+int pSLength(poly p, int l)
+{
+  int s=1;
+  int c=nSize(pGetCoeff(p));
+  pIter(p);
+  while (p!=NULL) { s+=nSize(pGetCoeff(p));pIter(p); }
+  return s*c;
+}
+int kSBucketLength(kBucket* b)
+{
+  int s=1;
+  int c=nSize(pGetCoeff(kBucketGetLm(b)));
+  int i;
+  for (i=MAX_BUCKET;i>0;i--)
+  {
+    if(b->buckets[i]==NULL) continue;
+    s+=pSLength(b->buckets[i],0);
+  }
+  return s*c;
+}
+#endif
+
+static int LObject_better_gen(const void* ap, const void* bp)
+{
+  LObject* a=*(LObject**)ap;
+  LObject* b=*(LObject**)bp;
+  return(pLmCmp(a->p,b->p));
+}
+static int red_object_better_gen(const void* ap, const void* bp)
+{
+
+
+  return(pLmCmp(((red_object*) ap)->p,((red_object*) bp)->p));
+}
+static int pair_better_gen2(const void* ap,const void* bp){
+  return(-pair_better_gen(ap,bp));
+}
+static int kFindDivisibleByInS_easy(kStrategy strat,const red_object & obj){
+  int i;
+  long not_sev=~obj.sev;
+  poly p=obj.p;
+  for(i=0;i<=strat->sl;i++){
+    if (pLmShortDivisibleBy(strat->S[i],strat->sevS[i],p,not_sev))
+      return i;
+  }
+  return -1;
+}
+static int posInPairs (sorted_pair_node**  p, int pn, sorted_pair_node* qe,calc_dat* c,int an=0)
+{
+  if(pn==0) return 0;
+
+  int length=pn-1;
+  int i;
+  //int an = 0;
+  int en= length;
+
+  if (pair_better(qe,p[en],c))
+    return length+1;
+
+  while(1)
+    {
+      //if (an >= en-1)
+      if(en-1<=an)
+      {
+        if (pair_better(p[an],qe,c)) return an;
+        return en;
+      }
+      i=(an+en) / 2;
+        if (pair_better(p[i],qe,c))
+          en=i;
+      else an=i;
+    }
+}
+static BOOLEAN  ascending(int* i,int top){
+  if(top<1) return TRUE;
+  if(i[top]<i[top-1]) return FALSE;
+  return ascending(i,top-1);
+}
+
+sorted_pair_node**  merge(sorted_pair_node** p, int pn,sorted_pair_node **q, int qn,calc_dat* c){
+  int i;
+  int* a= (int*) omalloc(qn*sizeof(int));
+//   int mc;
+//   PrintS("Debug\n");
+//   for(mc=0;mc<qn;mc++)
+// {
+
+//     wrp(q[mc]->lcm_of_lm);
+//     PrintS("\n");
+// }
+//    PrintS("Debug they are in\n");
+//   for(mc=0;mc<pn;mc++)
+// {
+
+//     wrp(p[mc]->lcm_of_lm);
+//     PrintS("\n");
+// }
+  int lastpos=0;
+  for(i=0;i<qn;i++){
+    lastpos=posInPairs(p,pn,q[i],c, max(lastpos-1,0));
+    //   cout<<lastpos<<"\n";
+    a[i]=lastpos;
+
+  }
+  if((pn+qn)>c->max_pairs){
+    p=(sorted_pair_node**) omrealloc(p,2*(pn+qn)*sizeof(sorted_pair_node*));
+    c->max_pairs=2*(pn+qn);
+  }
+  for(i=qn-1;i>=0;i--){
+    size_t size;
+    if(qn-1>i)
+      size=(a[i+1]-a[i])*sizeof(sorted_pair_node*);
+    else
+      size=(pn-a[i])*sizeof(sorted_pair_node*); //as indices begin with 0
+    memmove (p+a[i]+(1+i), p+a[i], size);
+    p[a[i]+i]=q[i];
+  }
+  omfree(a);
+  return p;
+}
+
+
+static BOOLEAN trivial_syzygie(int pos1,int pos2,poly bound,calc_dat* c){
+
+
+  poly p1=c->S->m[pos1];
+  poly p2=c->S->m[pos2];
+  ring r=c->r;
+  
+
+  if (pGetComp(p1) > 0 || pGetComp(p2) > 0)
+    return FALSE;
+  int i = 1;
+  poly m=NULL;
+  poly gcd1=c->gcd_of_terms[pos1];
+  poly gcd2=c->gcd_of_terms[pos2];
+  
+  if((gcd1!=NULL) && (gcd2!=NULL)) 
+    {
+      gcd1->next=gcd2; //may ordered incorrect
+      poly m=gcd_of_terms(gcd1,c->r);
+      gcd1->next=NULL;
+      
+    } 
+
+  if (m==NULL) 
+  {
+     loop
+      {
+	if (pGetExp(p1, i)+ pGetExp(p2, i) > pGetExp(bound,i))   return FALSE;
+	if (i == pVariables){
+	  PrintS("trivial");
+	  return TRUE;
+	}
+	i++;
+      }
+  }
+  else 
+  {
+    loop
+      {
+	if (pGetExp(p1, i)-pGetExp(m,i) + pGetExp(p2, i) > pGetExp(bound,i))   return FALSE;
+	if (i == pVariables){
+	  pDelete(&m);
+	  PrintS("trivial");
+	  return TRUE;
+	}
+	i++;
+      }
+  }
+
+  
+
+  
+}
+
+///returns position sets w as weight
+int find_best(red_object* r,int l, int u, int &w, calc_dat* c){
+  int best=l;
+  int i;
+  w=r[l].guess_quality(c);
+  for(i=l+1;i<=u;i++){
+    int w2=r[i].guess_quality(c);
+    if(w2<w){
+      w=w2;
+      best=i;
+    }
+   
+  }
+ return best;
+}
+
+#if 0 
+int find_best(red_object* r,int l, int u, int &w, calc_dat* c){
+
+  int sz=u-l+1;
+  int n=sz/10+1;
+  int filled=0;
+  int* indizes=(int*) omalloc(n*sizeof(int));
+  int* weight=(int*) omalloc(n*sizeof(int));
+  int worst=-1;
+  int i;  
+  for(i=l;i<=u;i++){
+    int q=r[i].guess_quality(c);
+    if ((filled<n)||(q<worst)){
+      if(filled<n){
+	worst=max(q,worst);
+	indizes[filled]=i;
+	weight[filled]=q;
+	filled++;
+      }
+    }
+    else{
+      int j;
+      for(j=0;j<filled;j++){
+	if (worst==weight[j]){
+	  weight[j]=q;
+	  indizes[j]=i;
+	}
+      }
+      worst=-1;
+      for(j=0;j<filled;j++){
+	if (worst<weight[j]){
+	  worst=weight[j];
+	}
+      }
+    }
+  }
+  assume(filled==n);
+  int pos=0;
+
+  for(i=0;i<filled;i++){  
+    r[indizes[i]].canonicalize();
+    weight[i]=r[indizes[i]].guess_quality(c);
+    if(weight[i]<weight[pos]) pos=i;
+  }
+  w=weight[pos];
+  pos=indizes[pos];
+
+  omfree(indizes);
+  omfree(weight);
+
+  assume(w==r[pos].guess_quality(c));
+  assume(l<=pos);
+  assume(u>=pos);
+  return pos;
+  
+}
+
+#endif
+void red_object::canonicalize(){
+  kBucketCanonicalize(bucket);
+  if(sum)
+    kBucketCanonicalize(sum->ac->bucket);
+  
+}
+BOOLEAN good_has_t_rep(int i, int j,calc_dat* c){
+  assume(i>=0);
+    assume(j>=0);
+  if (has_t_rep(i,j,c)) return TRUE;
+  poly lm=pOne();
+
+  pLcm(c->S->m[i], c->S->m[j], lm);
+  pSetm(lm);
+  assume(lm!=NULL);
+  int deciding_deg= pTotaldegree(lm);
+  int* i_con =make_connections(i,j,lm,c);
+  p_Delete(&lm,c->r);
+
+
+  for (int n=0;((n<c->n) && (i_con[n]>=0));n++){
+    if (i_con[n]==j){
+      now_t_rep(i,j,c);
+      omfree(i_con);
+
+      return TRUE;
+    }
+  }
+  omfree(i_con);
+
+  return FALSE;
+}
+BOOLEAN lenS_correct(kStrategy strat){
+  int i;
+  for(i=0;i<=strat->sl;i++){
+    if (strat->lenS[i]!=pLength(strat->S[i]))
+      return FALSE;
+  }
+  return TRUE;
+}
+
+static void notice_miss(int i, int j, calc_dat* c){
+  PrintS("-");
+ 
+}
+
+static void cleanS(kStrategy strat){
+  int i=0;
+  LObject P;
+  while(i<=strat->sl){
+    P.p=strat->S[i];
+    P.sev=strat->sevS[i];
+    if(kFindDivisibleByInS(strat->S,strat->sevS,strat->sl,&P)!=i){
+      deleteInS(i,strat);
+      //remember destroying poly
+    }
+    else i++;
+  }
+}
+static int bucket_guess(kBucket* bucket){
+  int sum=0;
+  int i;
+  for (i=MAX_BUCKET;i>=0;i--){
+    sum+=bucket->buckets_length[i];
+  }
+  return sum;
+}
+
+
+
+
+
+
+static int add_to_reductors(calc_dat* c, poly h, int len){
+  inDebug(h);
+  assume(lenS_correct(c->strat));
+ 
+  int i;
+  if (c->is_char0)
+       i=simple_posInS(c->strat,h,pSLength(h,len),c->is_char0);
+  else
+    i=simple_posInS(c->strat,h,len,c->is_char0);
+  
+  LObject P; memset(&P,0,sizeof(P));
+  P.tailRing=c->r;
+  P.p=h; /*p_Copy(h,c->r);*/
+  P.FDeg=pFDeg(P.p,c->r);
+  if (!rField_is_Zp(c->r)){ 
+    pCleardenom(P.p);
+    pContent(P.p); //is a duplicate call, but belongs here
+  }
+  
+  else                     
+    pNorm(P.p);
+ 
+ 
+  c->strat->enterS(P,i,c->strat);
+ 
+ 
+
+  c->strat->lenS[i]=len;
+ 
+  if(c->strat->lenSw)
+    c->strat->lenSw[i]=pSLength(P.p,len);
+  return i;
+ 
+}
+static void length_one_crit(calc_dat* c, int pos, int len)
+{
+  if (len==1)
+  {
+    int i;
+    for ( i=0;i<pos;i++)
+    {
+      if (c->lengths[i]==1)
+        c->states[pos][i]=HASTREP;
+    }
+    for ( i=pos+1;i<c->n;i++){
+      if (c->lengths[i]==1)
+        c->states[i][pos]=HASTREP;
+    }
+    shorten_tails(c,c->S->m[pos]);
+  }
+}
+static sorted_pair_node* find_next_pair2(calc_dat* c, BOOLEAN go_higher){
+  clean_top_of_pair_list(c);
+  sorted_pair_node* s=pop_pair(c);
+
+
+  return s;
+}
+
+static void move_forward_in_S(int old_pos, int new_pos,kStrategy strat, BOOLEAN is_char0)
+{
+  assume(old_pos>=new_pos);
+  poly p=strat->S[old_pos];
+  int ecart=strat->ecartS[old_pos];
+  long sev=strat->sevS[old_pos];
+  int s_2_r=strat->S_2_R[old_pos];
+  int length=strat->lenS[old_pos];
+  int length_w;
+  if(is_char0)
+    length_w=strat->lenSw[old_pos];
+  int i;
+  for (i=old_pos; i>new_pos; i--)
+  {
+    strat->S[i] = strat->S[i-1];
+    strat->ecartS[i] = strat->ecartS[i-1];
+    strat->sevS[i] = strat->sevS[i-1];
+    strat->S_2_R[i] = strat->S_2_R[i-1];
+  }
+  if (strat->lenS!=NULL)
+    for (i=old_pos; i>new_pos; i--)
+      strat->lenS[i] = strat->lenS[i-1];
+  if (strat->lenSw!=NULL)
+    for (i=old_pos; i>new_pos; i--)
+      strat->lenSw[i] = strat->lenSw[i-1];
+
+  strat->S[new_pos]=p;
+  strat->ecartS[new_pos]=ecart;
+  strat->sevS[new_pos]=sev;
+  strat->S_2_R[new_pos]=s_2_r;
+  strat->lenS[new_pos]=length;
+  if(is_char0)
+    strat->lenSw[new_pos]=length_w;
+  //assume(lenS_correct(strat));
+}
+static void replace_pair(int & i, int & j, calc_dat* c)
+{
+  c->soon_free=NULL;
+  int curr_deg;
+  poly lm=pOne();
+
+  pLcm(c->S->m[i], c->S->m[j], lm);
+  pSetm(lm);
+  int deciding_deg= pTotaldegree(lm);
+  int* i_con =make_connections(i,j,lm,c);
+  int z=0;
+
+  for (int n=0;((n<c->n) && (i_con[n]>=0));n++){
+    if (i_con[n]==j){
+      now_t_rep(i,j,c);
+      omfree(i_con);
+      p_Delete(&lm,c->r);
+      return;
+    }
+  }
+
+  int* j_con =make_connections(j,lm,c);
+  i= i_con[0];
+  j=j_con[0];
+  if(c->n>1){
+    if (i_con[1]>=0)
+      i=i_con[1];
+    else {
+      if (j_con[1]>=0)
+        j=j_con[1];
+    }
+  }
+  pLcm(c->S->m[i], c->S->m[j], lm);
+  pSetm(lm);
+  poly short_s;
+  curr_deg=pTotaldegree(lm);
+  int_pair_node* last=NULL;
+
+  for (int n=0;((n<c->n) && (j_con[n]>=0));n++){
+    for (int m=0;((m<c->n) && (i_con[m]>=0));m++){
+      pLcm(c->S->m[i_con[m]], c->S->m[j_con[n]], lm);
+      pSetm(lm);
+      if (pTotaldegree(lm)>=deciding_deg)
+      {
+        soon_t_rep(i_con[m],j_con[n],c);
+        int_pair_node* h= (int_pair_node*)omalloc(sizeof(int_pair_node));
+        if (last!=NULL)
+          last->next=h;
+        else
+          c->soon_free=h;
+        h->next=NULL;
+        h->a=i_con[m];
+        h->b=j_con[n];
+        last=h;
+      }
+      //      if ((comp_deg<curr_deg)
+      //  ||
+      //  ((comp_deg==curr_deg) &&
+      short_s=ksCreateShortSpoly(c->S->m[i_con[m]],c->S->m[j_con[n]],c->r);
+      if (short_s==NULL) {
+        i=i_con[m];
+        j=j_con[n];
+        now_t_rep(i_con[m],j_con[n],c);
+        p_Delete(&lm,c->r);
+        omfree(i_con);
+        omfree(j_con);
+
+        return;
+      }
+#ifdef QUICK_SPOLY_TEST
+      for (int dz=0;dz<=c->n;dz++){
+        if (dz==c->n) {
+          //have found not head reducing pair
+          i=i_con[m];
+          j=j_con[n];
+          p_Delete(&short_s,c->r);
+          p_Delete(&lm,c->r);
+          omfree(i_con);
+          omfree(j_con);
+
+          return;
+        }
+        if (p_LmDivisibleBy(c->S->m[dz],short_s,c->r)) break;
+      }
+#endif
+      int comp_deg(pTotaldegree(short_s));
+      p_Delete(&short_s,c->r);
+      if ((comp_deg<curr_deg))
+         
+      {
+        curr_deg=comp_deg;
+        i=i_con[m];
+        j=j_con[n];
+      }
+    }
+  }
+  p_Delete(&lm,c->r);
+  omfree(i_con);
+  omfree(j_con);
+  return;
+}
+
+
+static int* make_connections(int from, poly bound, calc_dat* c)
+{
+  ideal I=c->S;
+  int s=pTotaldegree(bound);
+  int* cans=(int*) omalloc(c->n*sizeof(int));
+  int* connected=(int*) omalloc(c->n*sizeof(int));
+  int cans_length=0;
+  connected[0]=from;
+  int connected_length=1;
+  long neg_bounds_short= ~p_GetShortExpVector(bound,c->r);
+  for (int i=0;i<c->n;i++){
+    if (c->T_deg[i]>s) continue;
+    if (i!=from){
+      if(p_LmShortDivisibleBy(I->m[i],c->short_Exps[i],bound,neg_bounds_short,c->r)){
+        cans[cans_length]=i;
+        cans_length++;
+      }
+    }
+  }
+  int not_yet_found=cans_length;
+  int con_checked=0;
+  int pos;
+  while((not_yet_found>0) && (con_checked<connected_length)){
+    pos=connected[con_checked];
+    for(int i=0;i<cans_length;i++){
+      if (cans[i]<0) continue;
+      if (has_t_rep(pos,cans[i],c))
+      {
+        connected[connected_length]=cans[i];
+        connected_length++;
+        cans[i]=-1;
+        --not_yet_found;
+      }
+    }
+    con_checked++;
+  }
+  if (connected_length<c->n){
+    connected[connected_length]=-1;
+  }
+  omfree(cans);
+  return connected;
+}
+static int* make_connections(int from, int to, poly bound, calc_dat* c)
+{
+  ideal I=c->S;
+  int s=pTotaldegree(bound);
+  int* cans=(int*) omalloc(c->n*sizeof(int));
+  int* connected=(int*) omalloc(c->n*sizeof(int));
+  cans[0]=to;
+  int cans_length=1;
+  connected[0]=from;
+  int last_cans_pos=-1;
+  int connected_length=1;
+  long neg_bounds_short= ~p_GetShortExpVector(bound,c->r);
+
+  int not_yet_found=cans_length;
+  int con_checked=0;
+  int pos;
+  BOOLEAN can_find_more=TRUE;
+  while(((not_yet_found>0) && (con_checked<connected_length))||can_find_more){
+    if ((con_checked<connected_length)&& (not_yet_found>0)){
+      pos=connected[con_checked];
+      for(int i=0;i<cans_length;i++){
+        if (cans[i]<0) continue;
+        if (has_t_rep(pos,cans[i],c))//||(trivial_syzygie(pos,cans[i],bound,c))
+{
+
+          connected[connected_length]=cans[i];
+          connected_length++;
+          cans[i]=-1;
+          --not_yet_found;
+
+          if (connected[connected_length-1]==to){
+            if (connected_length<c->n){
+              connected[connected_length]=-1;
+            }
+            omfree(cans);
+            return connected;
+          }
+        }
+      }
+      con_checked++;
+    }
+    else
+    {
+      for(last_cans_pos++;last_cans_pos<=c->n;last_cans_pos++){
+        if (last_cans_pos==c->n){
+          if (connected_length<c->n){
+            connected[connected_length]=-1;
+          }
+          omfree(cans);
+          return connected;
+        }
+        if ((last_cans_pos==from)||(last_cans_pos==to))
+          continue;
+        if(p_LmShortDivisibleBy(I->m[last_cans_pos],c->short_Exps[last_cans_pos],bound,neg_bounds_short,c->r)){
+          cans[cans_length]=last_cans_pos;
+          cans_length++;
+          break;
+        }
+      }
+      not_yet_found++;
+      for (int i=0;i<con_checked;i++){
+        if (has_t_rep(connected[i],last_cans_pos,c)){
+
+          connected[connected_length]=last_cans_pos;
+          connected_length++;
+          cans[cans_length-1]=-1;
+
+          --not_yet_found;
+          if (connected[connected_length-1]==to){
+            if (connected_length<c->n){
+              connected[connected_length]=-1;
+            }
+
+            omfree(cans);
+            return connected;
+          }
+          break;
+        }
+      }
+    }
+  }
+  if (connected_length<c->n){
+    connected[connected_length]=-1;
+  }
+
+  omfree(cans);
+  return connected;
+}
+#ifdef HEAD_BIN
+static inline poly p_MoveHead(poly p, omBin b)
+{
+  poly np;
+  omTypeAllocBin(poly, np, b);
+  memmove(np, p, b->sizeW*sizeof(long));
+  omFreeBinAddr(p);
+  return np;
+}
+#endif
+
+
+
+//len should be weighted length in char 0
+static int simple_posInS (kStrategy strat, poly p,int len, BOOLEAN is_char0)
+{
+
+
+  if(strat->sl==-1) return 0;
+  polyset set=strat->S;
+  intset setL=strat->lenS;
+  if (is_char0) setL=strat->lenSw;
+  int length=strat->sl;
+  int i;
+  int an = 0;
+  int en= length;
+
+  if ((len>setL[length])
+      || ((len==setL[length]) && (pLmCmp(set[length],p)== -1)))
+    return length+1;
+
+  loop
+  {
+    if (an >= en-1)
+    {
+      if ((len<setL[an])
+          || ((len==setL[an]) && (pLmCmp(set[an],p) == 1))) return an;
+      return en;
+    }
+    i=(an+en) / 2;
+    if ((len<setL[i])
+        || ((len==setL[i]) && (pLmCmp(set[i],p) == 1))) en=i;
+    //else if ((len>setL[i])
+    //|| ((len==setL[i]) && (pLmCmp(set[i],p) == -1))) an=i;
+    else an=i;
+  }
+}
+/*2
+ *if the leading term of p
+ *divides the leading term of some S[i] it will be canceled
+ */
+static inline void clearS (poly p, unsigned long p_sev,int l, int* at, int* k,
+                           kStrategy strat)
+{
+  assume(p_sev == pGetShortExpVector(p));
+  if (!pLmShortDivisibleBy(p,p_sev, strat->S[*at], ~ strat->sevS[*at])) return;
+  if (l>=strat->lenS[*at]) return;
+  PrintS("!");mflush();
+  //pDelete(&strat->S[*at]);
+  deleteInS((*at),strat);
+  (*at)--;
+  (*k)--;
+//  assume(lenS_correct(strat));
+}
+static sorted_pair_node** add_to_basis(poly h, int i_pos, int j_pos,calc_dat* c, int* ip)
+{
+
+  assume(h!=NULL);
+//  BOOLEAN corr=lenS_correct(c->strat);
+  BOOLEAN R_found=FALSE;
+  void* hp;
+
+  ++(c->n);
+  ++(c->S->ncols);
+  int i,j;
+  i=c->n-1;
+  sorted_pair_node** nodes=(sorted_pair_node**) omalloc(sizeof(sorted_pair_node*)*i);
+  int spc=0;
+  c->T_deg=(int*) omrealloc(c->T_deg,c->n*sizeof(int));
+  c->T_deg[i]=pTotaldegree(h);
+  hp=omrealloc(c->rep, c->n *sizeof(int));
+  if (hp!=NULL){
+    c->rep=(int*) hp;
+  } else {
+    exit(1);
+  }
+  c->short_Exps=(long *) omrealloc(c->short_Exps ,c->n*sizeof(long));
+
+  hp=omrealloc(c->lengths, c->n *sizeof(int));
+  if (hp!=NULL){
+    c->lengths=(int*) hp;
+  } else {
+    exit(1);
+  }
+  c->lengths[i]=pLength(h);
+  hp=omrealloc(c->states, c->n * sizeof(char*));
+ 
+    c->states=(char**) hp;
+  c->gcd_of_terms=(poly*) omrealloc(c->gcd_of_terms, c->n *sizeof(poly));
+  c->gcd_of_terms[i]=gcd_of_terms(h,c->r);
+  c->rep[i]=i;
+  hp=omalloc(i*sizeof(char));
+  if (hp!=NULL){
+    c->states[i]=(char*) hp;
+  } else {
+    exit(1);
+  }
+  hp=omrealloc(c->S->m,c->n*sizeof(poly));
+  if (hp!=NULL){
+    c->S->m=(poly*) hp;
+  } else {
+    exit(1);
+  }
+  c->S->m[i]=h;
+  c->short_Exps[i]=p_GetShortExpVector(h,c->r);
+  for (j=0;j<i;j++){
+    if (c->rep[j]==j){
+      //check product criterion
+
+      c->states[i][j]=UNCALCULATED;
+
+      //lies I[i] under I[j] ?
+      if(p_LmShortDivisibleBy(c->S->m[i],c->short_Exps[i],c->S->m[j],~(c->short_Exps[j]),c->r)){
+        c->rep[j]=i;
+	
+        PrintS("R"); R_found=TRUE;
+
+        c->Rcounter++;
+        if((i_pos>=0) && (j_pos>=0)){
+       
+        }
+        for(int z=0;z<j;z++){
+          if(c->rep[z]!=z) continue;
+          if (c->states[j][z]==UNCALCULATED){
+            c->states[j][z]=UNIMPORTANT;
+          }
+        }
+        for(int z=j+1;z<i;z++){
+          if(c->rep[z]!=z) continue;
+          if (c->states[z][j]==UNCALCULATED){
+            c->states[z][j]=UNIMPORTANT;
+          }
+        }
+      }
+    }
+    else {
+      c->states[i][j]=UNIMPORTANT;
+    }
+    if ((c->lengths[i]==1) && (c->lengths[j]==1))
+      c->states[i][j]=HASTREP;
+    else if (pHasNotCF(c->S->m[i],c->S->m[j])){
+      c->easy_product_crit++;
+      c->states[i][j]=HASTREP;
+    }
+                        else if(extended_product_criterion(c->S->m[i],c->gcd_of_terms[i],c->S->m[j],c->gcd_of_terms[j],c)){
+                                        c->states[i][j]=HASTREP;
+					c->extended_product_crit++;
+                                        //PrintS("E");
+                        }
+    if (c->states[i][j]==UNCALCULATED){
+
+      
+//      poly short_s=ksCreateShortSpoly(c->S->m[i],c->S->m[j],c->r);
+      //    if (short_s)
+      //    {
+        sorted_pair_node* s=(sorted_pair_node*) omalloc(sizeof(sorted_pair_node));
+        s->i=max(i,j);
+        s->j=min(i,j);
+        s->expected_length=c->lengths[i]+c->lengths[j]-2;
+      
+        poly lm=pOne();
+
+        pLcm(c->S->m[i], c->S->m[j], lm);
+        pSetm(lm);
+	s->deg=pTotaldegree(lm);
+        s->lcm_of_lm=lm;
+//          pDelete(&short_s);
+        //assume(lm!=NULL);
+        nodes[spc]=s;
+        spc++;
+	// }
+	//else
+	//{
+        //c->states[i][j]=HASTREP;
+	//}
+    }
+  }
+
+  add_to_reductors(c, h, c->lengths[c->n-1]);
+  //i=posInS(c->strat,c->strat->sl,h,0 /*ecart*/);
+
+  if (c->lengths[c->n-1]==1)
+    shorten_tails(c,c->S->m[c->n-1]);
+  //you should really update c->lengths, c->strat->lenS, and the oder of polys in strat if you sort after lengths
+
+  //for(i=c->strat->sl; i>0;i--)
+  //  if(c->strat->lenS[i]<c->strat->lenS[i-1]) printf("fehler bei %d\n",i);
+  if (c->Rcounter>50) {
+    c->Rcounter=0;
+    cleanS(c->strat);
+  }
+  if(!ip){
+    qsort(nodes,spc,sizeof(sorted_pair_node*),pair_better_gen2);
+ 
+    
+    c->apairs=merge(c->apairs,c->pair_top+1,nodes,spc,c);
+    c->pair_top+=spc;
+    clean_top_of_pair_list(c);
+    omfree(nodes);
+    return NULL;
+  }
+  {
+    *ip=spc;
+    return nodes;
+  }
+
+  
+
+}
+#if 0
+static poly redNF (poly h,kStrategy strat)
+{
+  int j = 0;
+  int z = 3;
+  unsigned long not_sev;
+
+  if (0 > strat->sl)
+  {
+    return h;
+  }
+  not_sev = ~ pGetShortExpVector(h);
+  loop
+    {
+      if (pLmShortDivisibleBy(strat->S[j], strat->sevS[j], h, not_sev))
+      {
+        //if (strat->interpt) test_int_std(strat->kIdeal);
+        /*- compute the s-polynomial -*/
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("red:");
+          wrp(h);
+          PrintS(" with ");
+          wrp(strat->S[j]);
+        }
+#endif
+        h = ksOldSpolyRed(strat->S[j],h,strat->kNoether);
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("\nto:");
+          wrp(h);
+          PrintLn();
+        }
+#endif
+        if (h == NULL) return NULL;
+        z++;
+        if (z>=10)
+        {
+          z=0;
+          pNormalize(h);
+        }
+        /*- try to reduce the s-polynomial -*/
+        j = 0;
+        not_sev = ~ pGetShortExpVector(h);
+      }
+      else
+      {
+        if (j >= strat->sl) return h;
+        j++;
+      }
+    }
+}
+#else
+
+static poly redNF2 (poly h,calc_dat* c , int &len, number&  m,int n)
+{
+  m=nInit(1);
+  if (h==NULL) return NULL;
+
+  assume(len==pLength(h));
+  kStrategy strat=c->strat;
+  if (0 > strat->sl)
+  {
+    return h;
+  }
+  int j;
+ 
+  LObject P(h);
+  P.SetShortExpVector();
+  P.bucket = kBucketCreate(currRing);
+  // BOOLEAN corr=lenS_correct(strat);
+  kBucketInit(P.bucket,P.p,len /*pLength(P.p)*/);
+  //int max_pos=simple_posInS(strat,P.p);
+  loop
+    {
+
+      j=kFindDivisibleByInS(strat->S,strat->sevS,strat->sl,&P);
+      if ((j>=0) && ((!n)||(strat->lenS[j]<=n)))
+      {
+
+	
+        nNormalize(pGetCoeff(P.p));
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("red:");
+          wrp(h);
+          PrintS(" with ");
+          wrp(strat->S[j]);
+        }
+#endif
+       
+        number coef=kBucketPolyRed(P.bucket,strat->S[j],
+                                   strat->lenS[j]/*pLength(strat->S[j])*/,
+                                   strat->kNoether);
+	number m2=nMult(m,coef);
+	nDelete(&m);
+	m=m2;
+        nDelete(&coef);
+        h = kBucketGetLm(P.bucket);
+	
+	if (h==NULL) {
+	  len=0;
+	  return 
+	  NULL;}
+        P.p=h;
+        P.t_p=NULL;
+        P.SetShortExpVector();
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("\nto:");
+          wrp(h);
+          PrintLn();
+        }
+#endif
+      }
+      else
+      {
+        kBucketClear(P.bucket,&(P.p),&len);
+        kBucketDestroy(&P.bucket);
+        pNormalize(P.p);
+	assume(len==(pLength(P.p)));
+        return P.p;
+      }
+    }
+}
+
+
+static poly redTailShort(poly h, kStrategy strat){
+
+  int sl=strat->sl;
+  int i;
+  int len=pLength(h);
+  for(i=0;i<=strat->sl;i++){
+    if(strat->lenS[i]>2)
+      break;
+  }
+  return(redNFTail(h,i-1,strat, len));
+}
+
+static void line_of_extended_prod(int fixpos,calc_dat* c){
+    if (c->gcd_of_terms[fixpos]==NULL)
+  {
+    c->gcd_of_terms[fixpos]=gcd_of_terms(c->S->m[fixpos],c->r);
+    if (c->gcd_of_terms[fixpos])
+    {
+      int i;
+      for(i=0;i<fixpos;i++)
+        if((c->states[fixpos][i]!=HASTREP)&& (extended_product_criterion(c->S->m[fixpos],c->gcd_of_terms[fixpos], c->S->m[i],c->gcd_of_terms[i],c)))
+{
+          c->states[fixpos][i]=HASTREP;
+	  c->extended_product_crit++;
+}     
+      for(i=fixpos+1;i<c->n;i++)
+        if((c->states[i][fixpos]!=HASTREP)&& (extended_product_criterion(c->S->m[fixpos],c->gcd_of_terms[fixpos], c->S->m[i],c->gcd_of_terms[i],c)))
+	{        c->states[i][fixpos]=HASTREP;
+	c->extended_product_crit++;
+	}
+    }
+  }
+}
+static void c_S_element_changed_hook(int pos, calc_dat* c){
+  length_one_crit(c,pos, c->lengths[pos]);
+  line_of_extended_prod(pos,c);
+}
+class poly_tree_node {
+public:
+  poly p;
+  poly_tree_node* l;
+  poly_tree_node* r;
+  int n;
+  poly_tree_node(int sn):l(NULL),r(NULL),n(sn){}
+};
+class exp_number_builder{
+public:
+  poly_tree_node* top_level;
+  int n;
+  int get_n(poly p);
+  exp_number_builder():top_level(0),n(0){}
+};
+int exp_number_builder::get_n(poly p){
+  poly_tree_node** node=&top_level;
+  while(*node!=NULL){
+    int c=pLmCmp(p,(*node)->p);
+    if (c==0) return (*node)->n;
+    if (c==-1) node=&((*node)->r);
+    else
+      node=&((*node)->l);
+  }
+  (*node)= new poly_tree_node(n);
+  n++;
+  (*node)->p=pLmInit(p);
+  return (*node)->n;
+}
+class mac_poly_r{
+public:
+  number coef;
+  mac_poly_r* next;
+  int exp;
+  mac_poly_r():next(NULL){}
+};
+//mac_polys exp are smaller iff they are greater by monomial ordering
+//corresponding to solving linear equations notation
+struct int_poly_pair{
+  poly p;
+  int n;
+};
+typedef mac_poly_r* mac_poly;
+  void t2ippa_rec(poly* ip,int* ia, poly_tree_node* k, int &offset){
+    if(!k) return;
+    t2ippa_rec(ip,ia,k->l,offset);
+    ip[offset]=k->p;
+    ia[k->n]=offset;
+    ++offset;
+
+    t2ippa_rec(ip,ia,k->r,offset);
+    delete k;
+  }
+void t2ippa(poly* ip,int* ia,exp_number_builder & e){
+
+  int o=0;
+  t2ippa_rec(ip,ia,e.top_level,o);
+}
+int anti_poly_order(const void* a, const void* b){
+  return -pLmCmp(((int_poly_pair*) a)->p,((int_poly_pair*) b)->p );
+}
+mac_poly mac_p_add_ff_qq(mac_poly a, number f,mac_poly b){
+  mac_poly erg;
+  mac_poly* set_this;
+  set_this=&erg;
+  while((a!=NULL) &&(b!=NULL)){
+    if (a->exp<b->exp){
+      (*set_this)=a;
+      a=a->next;
+      set_this= &((*set_this)->next);
+    } 
+    else{
+      if (a->exp>b->exp){
+	mac_poly in =new mac_poly_r();
+	in->exp=b->exp;
+	in->coef=nMult(b->coef,f);
+	(*set_this)=in;
+	b=b->next;
+	set_this= &((*set_this)->next);
+      }
+      else {
+	//a->exp==b->ecp
+	number n=nMult(b->coef,f);
+	number n2=nAdd(a->coef,n);
+	nDelete(&n);
+	nDelete(&(a->coef));
+	if (nIsZero(n2)){
+	  nDelete(&n2);
+	  mac_poly ao=a;
+	  a=a->next;
+	  delete ao;
+	  b=b->next;
+	  
+	} else {
+	  a->coef=n2;
+	  b=b->next;
+	  (*set_this)=a;
+	  a=a->next;
+	  set_this= &((*set_this)->next);
+	}
+ 
+      }
+    
+    }
+  }
+  if((a==NULL)&&(b==NULL)){
+    (*set_this)=NULL;
+    return erg;
+  }
+  if (b==NULL) {
+    (*set_this=a);
+    return erg;
+  }
+  
+  //a==NULL
+  while(b!=NULL){
+    mac_poly mp= new mac_poly_r();
+    mp->exp=b->exp;
+    mp->coef=nMult(f,b->coef);
+    (*set_this)=mp;
+    set_this=&(mp->next);
+    b=b->next;
+  }
+  (*set_this)=NULL;
+  return erg;
+  
+}
+void mac_mult_cons(mac_poly p,number c){
+  while(p){
+    number m=nMult(p->coef,c);
+    nDelete(&(p->coef));
+    p->coef=m;
+    p=p->next;
+  }
+  
+}
+int mac_length(mac_poly p){
+  int l=0;
+  while(p){
+    l++;
+    p=p->next;
+  }
+  return l;
+}
+BOOLEAN is_valid_ro(red_object & ro){
+  red_object r2=ro;
+  ro.validate();
+  if ((r2.p!=ro.p)||(r2.sev!=ro.sev)||(r2.sum!=ro.sum)) return FALSE;
+  return TRUE;
+}
+void pre_comp(poly* p,int & pn,calc_dat* c){
+  if(!(pn))
+    return;
+  mac_poly* q=(mac_poly*) omalloc(pn*sizeof(mac_poly)); 
+  int i;
+  exp_number_builder e;
+  for(i=0;i<pn;i++){
+    assume(p[i]!=NULL);
+    q[i]=new mac_poly_r();
+    q[i]->exp=e.get_n(p[i]);
+    q[i]->coef=nCopy(p[i]->coef);
+    
+    mac_poly qa=q[i];
+    poly pa=p[i];
+    while(pa->next!=NULL){
+      qa->next = new mac_poly_r();
+      qa=qa->next;
+      pa=pa->next,
+      qa->exp=e.get_n(pa);
+      qa->coef=nCopy(pa->coef);
+     
+      
+    }
+    qa->next=NULL;
+    pDelete(&p[i]);
+  }
+  poly* ip= (poly*)omalloc (e.n*sizeof(poly));
+  int* ia=(int*) omalloc (e.n*sizeof(int));
+  t2ippa(ip,ia,e);
+  for(i=0;i<pn;i++){
+    mac_poly mp=q[i];
+    while(mp!=NULL){
+      mp->exp=ia[mp->exp];
+      mp=mp->next;
+    }
+    
+  }
+//gaus reduction start
+  int col, row;
+  col=0;
+  row=0;
+  assume(pn>0);
+  while(row<pn-1){
+    //row is the row where pivot should be
+    // row== pn-1 means we have only to act on one row so no red nec.
+    //we assume further all rows till the pn-1 row are non-zero
+    
+    //select column
+    int i;
+    col=q[row]->exp;
+    int found_in_row=row;
+    for(i=row;i<pn;i++){
+      if(q[i]->exp<col){
+	col=q[i]->exp;
+	found_in_row=i;
+      }
+      
+    }
+    //select pivot
+    int act_l=mac_length(q[found_in_row]);
+    for(i=row+1;i<pn;i++){
+      if((q[i]->exp==col)&&(mac_length(q[i])<act_l)){
+	found_in_row=i;
+	act_l=mac_length(q[i]);//should be optimized here
+      }
+    }
+    mac_poly h=q[row];
+    q[row]=q[found_in_row];
+    q[found_in_row]=h;
+
+    //reduction
+    for(i=row+1;i<pn;i++){
+      if(q[i]->exp==q[row]->exp){
+	
+	number c1=nNeg(q[i]->coef);
+	number c2=q[row]->coef;
+	//use checkcoeff later
+	mac_mult_cons(q[i],c2);
+	q[i]=mac_p_add_ff_qq(q[i],c1,q[row]);
+      }
+	  
+	
+	
+    }
+    for(i=row+1;i<pn;i++){
+      if(q[i]==NULL){
+	q[i]=q[pn-1];
+	pn--;
+	if(i!=pn){i--;}
+      }
+    }
+  
+
+
+
+
+
+
+
+    row++;
+  }
+
+
+//gaus reduction end  
+
+
+
+
+
+  for(i=0;i<pn;i++){
+    poly pa;
+    mac_poly qa;
+    p[i]=pLmInit(ip[q[i]->exp]);
+    pSetCoeff(p[i],q[i]->coef);
+    pa=p[i];
+    qa=q[i];
+    while(qa->next!=NULL){
+      qa=qa->next;
+      pa->next=pLmInit(ip[qa->exp]);
+      pa=pa->next;
+      pa->coef=qa->coef;
+    }
+    pa->next=NULL;
+  }
+  for(i=0;i<e.n;i++){
+    pDelete(&ip[i]);  
+  }
+  omfree(ip);
+  omfree(ia);
+}
+
+static void go_on (calc_dat* c){
+  //set limit of 1000 for multireductions, at the moment for
+  //programming reasons
+  int i=0;
+  c->average_length=0;
+  for(i=0;i<c->n;i++){
+    c->average_length+=c->lengths[i];
+  }
+  c->average_length=c->average_length/c->n;
+  i=0;
+  poly* p=(poly*) omalloc((PAR_N+1)*sizeof(poly));//nullterminated
+
+  int curr_deg=-1;
+  while(i<PAR_N){
+    sorted_pair_node* s=top_pair(c);
+    if (!s) break;
+    if(curr_deg>=0){
+      if (s->deg >curr_deg) break;
+    }
+
+    else curr_deg=s->deg;
+    quick_pop_pair(c);
+    if(s->i>=0){
+      //replace_pair(s->i,s->j,c);
+    if(s->i==s->j) {
+      free_sorted_pair_node(s,c->r);
+      continue;
+	}
+    }
+    poly h;
+    if(s->i>=0)
+      h=ksOldCreateSpoly(c->S->m[s->i], c->S->m[s->j], NULL, c->r);
+    else
+      h=s->lcm_of_lm;
+    if(s->i>=0)
+      now_t_rep(s->j,s->i,c);
+    number coef;
+    int mlen=pLength(h);
+    h=redNF2(h,c,mlen,coef,2);
+    redTailShort(h,c->strat);
+    nDelete(&coef);
+
+    free_sorted_pair_node(s,c->r);
+    if(!h) continue;
+    int len=pLength(h);
+    p[i]=h;
+    
+    i++;
+  }
+  p[i]=NULL;
+//  pre_comp(p,i,c);
+  if(i==0){
+    omfree(p);
+    return;
+  }
+  red_object* buf=(red_object*) omalloc(i*sizeof(red_object));
+  c->normal_forms+=i;
+  int j;
+  for(j=0;j<i;j++){
+    buf[j].p=p[j];
+    buf[j].sev=pGetShortExpVector(p[j]);
+    buf[j].sum=NULL;
+    buf[j].bucket = kBucketCreate(currRing);
+    int len=pLength(p[j]);
+    kBucketInit(buf[j].bucket,buf[j].p,len);
+  }
+  omfree(p);
+  qsort(buf,i,sizeof(red_object),red_object_better_gen);
+//    Print("\ncurr_deg:%i\n",curr_deg);
+  Print("M[%i, ",i);  
+  multi_reduction(buf, i, c);
+  Print("%i]",i); 
+ //  for(j=0;j<i;j++){
+//     if(buf[j].p==NULL) PrintS("\n ZERO ALERT \n");
+//     int z;
+//      for(z=0;z<j;z++){
+//       if (pLmEqual(buf[z].p, buf[j].p))
+// 	PrintS("\n Critical Warning!!!! \n");
+      
+//     }
+//   }
+  int* ibuf=(int*) omalloc(i*sizeof(int));
+  sorted_pair_node*** sbuf=(sorted_pair_node***) omalloc(i*sizeof(sorted_pair_node**));
+  for(j=0;j<i;j++){
+ 
+ 
+    int len;
+    poly p;
+    buf[j].flatten();
+    kBucketClear(buf[j].bucket,&p, &len);
+    kBucketDestroy(&buf[j].bucket);
+    // delete buf[j];
+    //remember to free res here
+    p=redTailShort(p, c->strat);
+    sbuf[j]=add_to_basis(p,-1,-1,c,ibuf+j);
+    
+  }
+  int sum=0;
+  for(j=0;j<i;j++){
+    sum+=ibuf[j];
+  }
+  sorted_pair_node** big_sbuf=(sorted_pair_node**) omalloc(sum*sizeof(sorted_pair_node*));
+  int partsum=0;
+  for(j=0;j<i;j++){
+    memmove(big_sbuf+partsum, sbuf[j],ibuf[j]*sizeof(sorted_pair_node*));
+    omfree(sbuf[j]);
+    partsum+=ibuf[j];
+  }
+
+  qsort(big_sbuf,sum,sizeof(sorted_pair_node*),pair_better_gen2);
+  c->apairs=merge(c->apairs,c->pair_top+1,big_sbuf,sum,c);
+  c->pair_top+=sum;
+  clean_top_of_pair_list(c);
+  omfree(big_sbuf);
+  omfree(sbuf);
+  omfree(ibuf);
+  omfree(buf);
+  return;
+}
+
+static poly redNF (poly h,kStrategy strat, int &len)
+{
+  len=0;
+  if (h==NULL) return NULL;
+  int j;
+
+  len=pLength(h);
+  if (0 > strat->sl)
+  {
+    return h;
+  }
+  LObject P(h);
+  P.SetShortExpVector();
+  P.bucket = kBucketCreate(currRing);
+  kBucketInit(P.bucket,P.p,len /*pLength(P.p)*/);
+  //int max_pos=simple_posInS(strat,P.p);
+  loop
+    {
+      j=kFindDivisibleByInS(strat->S,strat->sevS,strat->sl,&P);
+      if (j>=0)
+      {
+        nNormalize(pGetCoeff(P.p));
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("red:");
+          wrp(h);
+          PrintS(" with ");
+          wrp(strat->S[j]);
+        }
+#endif
+        number coef=kBucketPolyRed(P.bucket,strat->S[j],
+                                   strat->lenS[j]/*pLength(strat->S[j])*/,
+                                   strat->kNoether);
+        nDelete(&coef);
+        h = kBucketGetLm(P.bucket);
+        if (h==NULL) return NULL;
+        P.p=h;
+        P.t_p=NULL;
+        P.SetShortExpVector();
+#ifdef KDEBUG
+        if (TEST_OPT_DEBUG)
+        {
+          PrintS("\nto:");
+          wrp(h);
+          PrintLn();
+        }
+#endif
+      }
+      else
+      {
+        kBucketClear(P.bucket,&(P.p),&len);
+        kBucketDestroy(&P.bucket);
+        pNormalize(P.p);
+        return P.p;
+      }
+    }
+}
+#endif
+#ifdef REDTAIL_S
+
+static poly redNFTail (poly h,const int sl,kStrategy strat, int len)
+{
+  if (h==NULL) return NULL;
+  pTest(h);
+  if (0 > sl)
+    return h;
+  if (pNext(h)==NULL) return h;
+
+  int j;
+  poly res=h;
+  poly act=res;
+  LObject P(pNext(h));
+  pNext(res)=NULL;
+  P.bucket = kBucketCreate(currRing);
+  len--;
+  h=P.p;
+  if (len <=0) len=pLength(h);
+  kBucketInit(P.bucket,h /*P.p*/,len /*pLength(P.p)*/);
+  pTest(h);
+  loop
+    {
+      P.p=h;
+      P.t_p=NULL;
+      P.SetShortExpVector();
+      loop
+        {
+          j=kFindDivisibleByInS(strat->S,strat->sevS,sl,&P);
+          if (j>=0)
+          {
+#ifdef REDTAIL_PROT
+            PrintS("r");
+#endif
+            nNormalize(pGetCoeff(P.p));
+#ifdef KDEBUG
+            if (TEST_OPT_DEBUG)
+            {
+              PrintS("red tail:");
+              wrp(h);
+              PrintS(" with ");
+              wrp(strat->S[j]);
+            }
+#endif
+            number coef;
+            pTest(strat->S[j]);
+            coef=kBucketPolyRed(P.bucket,strat->S[j],
+                                strat->lenS[j]/*pLength(strat->S[j])*/,strat->kNoether);
+            pMult_nn(res,coef);
+            nDelete(&coef);
+            h = kBucketGetLm(P.bucket);
+            pTest(h);
+            if (h==NULL)
+            {
+#ifdef REDTAIL_PROT
+              PrintS(" ");
+#endif
+              return res;
+            }
+            pTest(h);
+            P.p=h;
+            P.t_p=NULL;
+            P.SetShortExpVector();
+#ifdef KDEBUG
+            if (TEST_OPT_DEBUG)
+            {
+              PrintS("\nto tail:");
+              wrp(h);
+              PrintLn();
+            }
+#endif
+          }
+          else
+          {
+#ifdef REDTAIL_PROT
+            PrintS("n");
+#endif
+            break;
+          }
+        } /* end loop current mon */
+      poly tmp=pHead(h /*kBucketGetLm(P.bucket)*/);
+      act->next=tmp;pIter(act);
+      poly tmp2=pHead(h);
+      pNeg(tmp2);
+      int ltmp2=1;
+      pTest(tmp2);
+      kBucket_Add_q(P.bucket, tmp2, &ltmp2);
+
+      h = kBucketGetLm(P.bucket);
+      if (h==NULL)
+      {
+#ifdef REDTAIL_PROT
+        PrintS(" ");
+#endif
+        return res;
+      }
+      pTest(h);
+    }
+}
+#endif
+
+static void do_this_spoly_stuff(int i,int j,calc_dat* c){
+  poly f=c->S->m[i];
+  poly g=c->S->m[j];
+  poly h=ksOldCreateSpoly(f, g, NULL, c->r);
+  poly hr=NULL;
+#ifdef FULLREDUCTIONS
+  if (h!=NULL)
+  {
+    int len;
+
+//    hr=redNF2(h,c,len);
+//      hr=redNF(h,c->strat,len);
+
+    if (hr!=NULL)
+#ifdef REDTAIL_S
+      hr = redNFTail(hr,c->strat->sl,c->strat,len);
+#else
+    hr = redtailBba(hr,c->strat->sl,c->strat);
+#endif
+
+  }
+#else
+  if (h!=NULL)
+  {
+    int len;
+//    hr=redNF2(h,c,len);
+  }
+#endif
+  c->normal_forms++;
+  if (hr==NULL)
+  {
+    notice_miss(i, j, c);
+
+  }
+  else
+  {
+
+#ifdef HEAD_BIN
+    hr=p_MoveHead(hr,c->HeadBin);
+#endif
+    add_to_basis(hr, i,j,c);
+  }
+}
+//try to fill, return FALSE iff queue is empty
+
+static int poly_crit(const void* ap1, const void* ap2){
+  poly p1,p2;
+  p1=*((poly*) ap1);
+  p2=*((poly*)ap2);
+
+  int c=pLmCmp(p1,p2);
+  if (c !=0) return c;
+  int l1=pLength(p1);
+  int l2=pLength(p2);
+  if (l1<l2) return -1;
+  if (l1>l2) return 1;
+  return 0;
+}
+ideal t_rep_gb(ring r,ideal arg_I, ideal arg_debug_Ideal){
+  debug_Ideal=arg_debug_Ideal;
+  if (debug_Ideal) PrintS("DebugIdeal received\n");
+   Print("Idelems %i \n----------\n",IDELEMS(arg_I));
+  ideal I=idCompactify(arg_I);
+  qsort(I->m,IDELEMS(I),sizeof(poly),poly_crit);
+  Print("Idelems %i \n----------\n",IDELEMS(I));
+  calc_dat* c=(calc_dat*) omalloc(sizeof(calc_dat));
+  c->r=currRing;
+  void* h;
+  poly hp;
+  int i,j;
+  c->easy_product_crit=0;
+  c->extended_product_crit=0;
+  c->is_char0=(rChar()==0);
+  c->reduction_steps=0;
+  c->last_index=-1;
+
+
+
+  c->Rcounter=0;
+
+  c->soon_free=NULL;
+
+
+  c->normal_forms=0;
+  c->current_degree=1;
+ 
+  c->max_pairs=5*I->idelems();
+ 
+  c->apairs=(sorted_pair_node**) omalloc(sizeof(sorted_pair_node*)*c->max_pairs);
+  c->pair_top=-1;
+  int n=I->idelems();
+  for (i=0;i<n;i++){
+    wrp(I->m[i]);
+    PrintS("\n");
+  }
+    i=0;
+  c->n=0;
+  c->T_deg=(int*) omalloc(n*sizeof(int));
+ 
+#ifdef HEAD_BIN
+  c->HeadBin=omGetSpecBin(POLYSIZE + (currRing->ExpL_Size)*sizeof(long));
+#endif
+  /* omUnGetSpecBin(&(c->HeadBin)); */
+  h=omalloc(n*sizeof(char*));
+  c->states=(char**) h;
+  h=omalloc(n*sizeof(int));
+  c->lengths=(int*) h;
+  h=omalloc(n*sizeof(int));
+        c->gcd_of_terms=(poly*) omalloc(n*sizeof(poly));
+  c->rep=(int*) h;
+  c->short_Exps=(long*) omalloc(n*sizeof(long));
+  c->S=idInit(n,1);
+  c->strat=new skStrategy;
+  c->strat->syzComp = 0;
+  initBuchMoraCrit(c->strat);
+  initBuchMoraPos(c->strat);
+  c->strat->initEcart = initEcartBBA;
+  c->strat->enterS = enterSBba;
+  c->strat->sl = -1;
+  i=n;
+  /* initS(c->S,NULL,c->strat); */
+/* intS start: */
+  i=((i+IDELEMS(c->S)+15)/16)*16;
+  c->strat->ecartS=(intset)omAlloc(i*sizeof(int)); /*initec(i);*/
+  c->strat->sevS=(unsigned long*)omAlloc0(i*sizeof(unsigned long));
+  /*initsevS(i);*/
+  c->strat->S_2_R=(int*)omAlloc0(i*sizeof(int));/*initS_2_R(i);*/
+  c->strat->fromQ=NULL;
+  c->strat->Shdl=idInit(1,1);
+  c->strat->S=c->strat->Shdl->m;
+  c->strat->lenS=(int*)omAlloc0(i*sizeof(int));
+  if(c->is_char0)
+    c->strat->lenSw=(int*)omAlloc0(i*sizeof(int));
+  else
+    c->strat->lenSw=NULL;
+  sorted_pair_node* si;
+  assume(n>0);
+  add_to_basis(I->m[0],-1,-1,c);
+
+  assume(c->strat->sl==c->strat->Shdl->idelems()-1);
+
+  for (i=1;i<n;i++)//the 1 is wanted, because first element is added to basis
+   {
+//     add_to_basis(I->m[i],-1,-1,c);
+     si=(sorted_pair_node*) omalloc(sizeof(sorted_pair_node));
+      si->i=-1;
+      si->j=-1;
+      si->expected_length=pLength(I->m[i]);
+      si->deg=pTotaldegree(I->m[i]);
+      si->lcm_of_lm=I->m[i];
+
+//      c->apairs[n-1-i]=si;
+      c->apairs[n-i-1]=si;
+      ++(c->pair_top);
+   }
+ 
+
+  while(c->pair_top>=0)
+    go_on(c);
+
+  for(int z=0;z<c->n;z++){
+    omfree(c->states[z]);
+  }
+  omfree(c->states);
+  omfree(c->lengths);
+
+
+  omfree(c->short_Exps);
+  omfree(c->T_deg);
+
+     omFree(c->strat->ecartS);
+     omFree(c->strat->sevS);
+//   /*initsevS(i);*/
+   omFree(c->strat->S_2_R);
+   
+
+  omFree(c->strat->lenS);
+
+   if(c->strat->lenSw)  omFree(c->strat->lenSw);
+
+
+
+
+  for(i=0;i<c->n;i++){
+    if(c->gcd_of_terms[i])
+      pDelete(&(c->gcd_of_terms[i]));
+  }
+  omfree(c->gcd_of_terms);
+
+  omfree(c->apairs);
+  printf("calculated %d NFs\n",c->normal_forms);
+  printf("applied %i product crit, %i extended_product crit \n", c->easy_product_crit, c->extended_product_crit);
+  int deleted_form_c_s=0;
+
+  for(i=0;i<c->n;i++){
+    if (c->rep[i]!=i){
+      for(j=0;j<=c->strat->sl;j++){
+	if(c->strat->S[j]==c->S->m[i]){
+	  c->strat->S[j]=NULL;
+	  break;
+	}
+      }
+//      PrintS("R_delete");
+      pDelete(&c->S->m[i]);
+    }
+  }
+  for(i=0;i<=c->strat->sl;i++){
+    if (!c->strat->S[i]) continue;
+    BOOLEAN found=FALSE;
+    for(j=0;j<c->n;j++){
+      if (c->S->m[j]==c->strat->S[i]){
+	found=TRUE;
+	break;
+      }
+    }
+    if(!found) pDelete(&c->strat->S[i]);
+  }
+  omfree(c->rep);
+  I=c->S;
+  
+  IDELEMS(I)=c->n;
+
+  idSkipZeroes(c->S);
+  for(i=0;i<=c->strat->sl;i++)
+    c->strat->S[i]=NULL;
+  id_Delete(&c->strat->Shdl,c->r);
+  delete c->strat;
+  omfree(c);
+
+  return(I);
+}
+static void now_t_rep(const int & arg_i, const int & arg_j, calc_dat* c){
+  int i,j;
+  if (arg_i==arg_j){
+    return;
+  }
+  if (arg_i>arg_j){
+    i=arg_j;
+    j=arg_i;
+  } else {
+    i=arg_i;
+    j=arg_j;
+  }
+  c->states[j][i]=HASTREP;
+}
+static void soon_t_rep(const int& arg_i, const int& arg_j, calc_dat* c)
+{
+  assume(0<=arg_i);
+  assume(0<=arg_j);
+  assume(arg_i<c->n);
+  assume(arg_j<c->n);
+  int i,j;
+  if (arg_i==arg_j){
+    return;
+  }
+  if (arg_i>arg_j){
+    i=arg_j;
+    j=arg_i;
+  } else {
+    i=arg_i;
+    j=arg_j;
+  }
+  if (!
+      (c->states[j][i]==HASTREP))
+    c->states[j][i]=SOONTREP;
+}
+static BOOLEAN has_t_rep(const int & arg_i, const  int & arg_j, calc_dat* state){
+  assume(0<=arg_i);
+  assume(0<=arg_j);
+  assume(arg_i<state->n);
+  assume(arg_j<state->n);
+  if (arg_i==arg_j)
+  {
+    return (TRUE);
+  }
+  if (arg_i>arg_j)
+  {
+    return (state->states[arg_i][arg_j]==HASTREP);
+  } else
+  {
+    return (state->states[arg_j][arg_i]==HASTREP);
+  }
+}
+static int pLcmDeg(poly a, poly b)
+{
+  int i;
+  int n=0;
+  for (i=pVariables; i; i--)
+  {
+    n+=max( pGetExp(a,i), pGetExp(b,i));
+  }
+  return n;
+
+}
+
+
+
+static void shorten_tails(calc_dat* c, poly monom)
+{
+  return;
+// BOOLEAN corr=lenS_correct(c->strat);
+  for(int i=0;i<c->n;i++)
+  {
+    //enter tail
+    if (c->rep[i]!=i) continue;
+    if (c->S->m[i]==NULL) continue;
+    poly tail=c->S->m[i]->next;
+    poly prev=c->S->m[i];
+    BOOLEAN did_something=FALSE;
+    while((tail!=NULL)&& (pLmCmp(tail, monom)>=0))
+    {
+      if (p_LmDivisibleBy(monom,tail,c->r))
+      {
+        did_something=TRUE;
+        prev->next=tail->next;
+        tail->next=NULL;
+        p_Delete(& tail,c->r);
+        tail=prev;
+        //PrintS("Shortened");
+        c->lengths[i]--;
+      }
+      prev=tail;
+      tail=tail->next;
+    }
+    if (did_something)
+    {
+      int new_pos;
+      int q;
+      q=quality(c->S->m[i],c->lengths[i],c);
+      new_pos=simple_posInS(c->strat,c->S->m[i],q,c->is_char0);
+
+      int old_pos=-1;
+      //assume new_pos<old_pos
+      for (int z=0;z<=c->strat->sl;z++)
+      {
+        if (c->strat->S[z]==c->S->m[i])
+        {
+          old_pos=z;
+          break;
+        }
+      }
+      if (old_pos== -1)
+        for (int z=new_pos-1;z>=0;z--)
+        {
+          if (c->strat->S[z]==c->S->m[i])
+          {
+            old_pos=z;
+            break;
+          }
+        }
+      assume(old_pos>=0);
+      assume(new_pos<=old_pos);
+      assume(pLength(c->strat->S[old_pos])==c->lengths[i]);
+      c->strat->lenS[old_pos]=c->lengths[i];
+      if (c->strat->lenSw)
+        c->strat->lenSw[old_pos]=q;
+
+      if (new_pos<old_pos)
+        move_forward_in_S(old_pos,new_pos,c->strat, c->is_char0);
+
+      length_one_crit(c,i,c->lengths[i]);
+    }
+  }
+}
+static sorted_pair_node* pop_pair(calc_dat* c){
+  clean_top_of_pair_list(c);
+
+  if(c->pair_top<0) return NULL;
+  else return (c->apairs[c->pair_top--]);
+}
+static sorted_pair_node* top_pair(calc_dat* c){
+  super_clean_top_of_pair_list(c);//yeah, I know, it's odd that I use a different proc here
+
+  if(c->pair_top<0) return NULL;
+  else return (c->apairs[c->pair_top]);
+}
+static sorted_pair_node* quick_pop_pair(calc_dat* c){
+  if(c->pair_top<0) return NULL;
+  else return (c->apairs[c->pair_top--]);
+}
+static BOOLEAN no_pairs(calc_dat* c){
+  clean_top_of_pair_list(c);
+  return (c->pair_top==-1);
+}
+
+
+static void super_clean_top_of_pair_list(calc_dat* c){
+  while((c->pair_top>=0) && (c->apairs[c->pair_top]->i>=0) && (good_has_t_rep(c->apairs[c->pair_top]->j, c->apairs[c->pair_top]->i,c))){
+
+    free_sorted_pair_node(c->apairs[c->pair_top],c->r);
+    c->pair_top--;
+
+  }
+}
+static void clean_top_of_pair_list(calc_dat* c){
+  while((c->pair_top>0) && (c->apairs[c->pair_top]->i>=0) && (!state_is(UNCALCULATED,c->apairs[c->pair_top]->j, c->apairs[c->pair_top]->i,c))){
+
+    free_sorted_pair_node(c->apairs[c->pair_top],c->r);
+    c->pair_top--;
+
+  }
+}
+static BOOLEAN state_is(calc_state state, const int & arg_i, const  int & arg_j, calc_dat* c){
+  assume(0<=arg_i);
+  assume(0<=arg_j);
+  assume(arg_i<c->n);
+  assume(arg_j<c->n);
+  if (arg_i==arg_j)
+  {
+    return (TRUE);
+  }
+  if (arg_i>arg_j)
+  {
+    return (c->states[arg_i][arg_j]==state);
+  }
+  else return(c->states[arg_j][arg_i]==state);
+}
+static void free_sorted_pair_node(sorted_pair_node* s, ring r){
+  if (s->i>=0)
+    p_Delete(&s->lcm_of_lm,r);
+  omfree(s);
+}
+static BOOLEAN pair_better(sorted_pair_node* a,sorted_pair_node* b, calc_dat* c){
+  if (a->deg<b->deg) return TRUE;
+  if (a->deg>b->deg) return FALSE;
+
+  if (a->expected_length<b->expected_length) return TRUE;
+  if (a->expected_length>b->expected_length) return FALSE;
+  int comp=pLmCmp(a->lcm_of_lm, b->lcm_of_lm);
+  if (comp==1) return FALSE;
+  if (-1==comp) return TRUE;
+  if (a->i<b->i) return TRUE;
+  if (a->j<b->j) return TRUE;
+  return FALSE;
+}
+
+static int pair_better_gen(const void* ap,const void* bp){
+
+  sorted_pair_node* a=*((sorted_pair_node**)ap);
+  sorted_pair_node* b=*((sorted_pair_node**)bp);
+  assume(a->i>a->j);
+  assume(b->i>b->j);
+  if (a->deg<b->deg) return -1;
+  if (a->deg>b->deg) return 1;
+
+
+  if (a->expected_length<b->expected_length) return -1;
+  if (a->expected_length>b->expected_length) return 1;
+ int comp=pLmCmp(a->lcm_of_lm, b->lcm_of_lm);
+  
+  if (comp==1) return 1;
+  if (-1==comp) return -1;
+  if (a->i<b->i) return -1;
+  if (a->j<b->j) return -1;
+  return 0;
+}
+
+
+static poly gcd_of_terms(poly p, ring r){
+  int max_g_0=0;
+  assume(p!=NULL);
+  int i;
+  poly m=pOne();
+  poly t;
+  for (i=pVariables; i; i--)
+  {
+      pSetExp(m,i, pGetExp(p,i));
+      if (max_g_0==0)
+	if (pGetExp(m,i)>0)
+	  max_g_0=i;
+  }
+  
+  t=p->next;
+  while (t!=NULL){
+    
+    if (max_g_0==0) break;
+    for (i=pVariables; i; i--)
+    {
+      pSetExp(m,i, min(pGetExp(t,i),pGetExp(m,i)));
+      if (max_g_0==i)
+	if (pGetExp(m,i)==0)
+	  max_g_0=0;
+      if ((max_g_0==0) && (pGetExp(m,i)>0)){
+	max_g_0=i;
+      }
+    }
+                t=t->next;
+  }
+        for (i=pVariables;i;i--)
+        {
+                if(pGetExp(m,i)>0)
+                        return m;
+  }
+        pDelete(&m);
+  return NULL;
+}
+static BOOLEAN pHasNotCFExtended(poly p1, poly p2, poly m)
+{
+
+  if (pGetComp(p1) > 0 || pGetComp(p2) > 0)
+    return FALSE;
+  int i = 1;
+  loop
+  {
+    if ((pGetExp(p1, i)-pGetExp(m,i) >0) && (pGetExp(p2, i) -pGetExp(m,i)> 0))   return FALSE;
+    if (i == pVariables)                                return TRUE;
+    i++;
+  }
+}
+
+
+//for impl reasons may return false if the the normal product criterion matches
+static BOOLEAN extended_product_criterion(poly p1, poly gcd1, poly p2, poly gcd2, calc_dat* c){
+  if(gcd1==NULL) return FALSE;
+        if(gcd2==NULL) return FALSE;
+        gcd1->next=gcd2; //may ordered incorrect
+        poly m=gcd_of_terms(gcd1,c->r);
+        gcd1->next=NULL;
+        if (m==NULL) return FALSE;
+
+        BOOLEAN erg=pHasNotCFExtended(p1,p2,m);
+        pDelete(&m);
+        return erg;
+}
+static poly kBucketGcd(kBucket* b, ring r)
+{
+  int s=0;
+  int i;
+  poly m, n;
+  BOOLEAN initialized=FALSE;
+  for (i=MAX_BUCKET-1;i>=0;i--)
+  { 
+    if (b->buckets[i]!=NULL){
+      if (!initialized){
+	m=gcd_of_terms(b->buckets[i],r);
+	initialized=TRUE;
+	if (m==NULL) return NULL;
+      }
+      else
+	{
+	  n=gcd_of_terms(b->buckets[i],r);
+	  if (n==NULL) {
+	    pDelete(&m);
+	    return NULL;    
+	  }
+	  n->next=m;
+	  poly t=gcd_of_terms(n,r);
+	  n->next=NULL;
+	  pDelete(&m);
+	  pDelete(&n);
+	  m=t;
+	  if (m==NULL) return NULL;
+	  
+	}
+    }
+  }
+  return m;
+}
+
+
+
+static int guess_quality(const red_object & p, calc_dat* c){
+  //looks only on bucket
+  if (c->is_char0) return kSBucketLength(p.bucket);
+  return (bucket_guess(p.bucket));
+}
+static int quality_of_pos_in_strat_S(int pos, calc_dat* c){
+  if (c->is_char0) return c->strat->lenSw[pos];
+  return c->strat->lenS[pos];
+}
+static int quality(poly p, int len, calc_dat* c){
+  if (c->is_char0) return pSLength(p,len);
+  return pLength(p);
+}
+static void multi_reduction_lls_trick(red_object* los, int losl,calc_dat* c,find_erg & erg){
+  erg.expand=NULL;
+  BOOLEAN swap_roles; //from reduce_by, to_reduce_u if fromS
+  if(erg.fromS){
+    if(pLmEqual(c->strat->S[erg.reduce_by],los[erg.to_reduce_u].p))
+    {
+      int i;
+      int quality_a=quality_of_pos_in_strat_S(erg.reduce_by,c);
+      int best=erg.to_reduce_u+1;
+/*
+      for (i=erg.to_reduce_u;i>=erg.to_reduce_l;i--){
+	int qc=los[i].guess_quality(c);
+	if (qc<quality_a){
+	  best=i;
+	  quality_a=qc;
+	}
+      }
+      if(best!=erg.to_reduce_u+1){*/
+      int qc;
+      best=find_best(los,erg.to_reduce_l,erg.to_reduce_u,qc,c);
+      assume(qc==los[best].guess_quality(c));
+      if(qc<quality_a){
+	red_object h=los[erg.to_reduce_u];
+	los[erg.to_reduce_u]=los[best];
+	los[best]=h;
+	swap_roles=TRUE;
+      }
+      else{
+	
+	swap_roles=FALSE;
+      }
+  
+    }
+      else
+    {
+      if (erg.to_reduce_u>erg.to_reduce_l){
+
+	int i;
+	int quality_a=quality_of_pos_in_strat_S(erg.reduce_by,c);
+	int best=erg.to_reduce_u+1;
+	int qc;
+	best=find_best(los,erg.to_reduce_l,erg.to_reduce_u,qc,c);
+	assume(qc==los[best].guess_quality(c));
+	if(qc<quality_a){
+	  //(best!=erg.to_reduce_u+1){
+	  red_object h=los[erg.to_reduce_l];
+	  los[erg.to_reduce_l]=los[best];
+	  los[best]=h;
+	  erg.reduce_by=erg.to_reduce_l;
+	  erg.fromS=FALSE;
+	  erg.to_reduce_l++;
+	  
+	}
+      }
+      else 
+      {
+	assume(erg.to_reduce_u==erg.to_reduce_l);
+	int quality_a=quality_of_pos_in_strat_S(erg.reduce_by,c);
+	int qc=los[erg.to_reduce_u].guess_quality(c);
+	if(qc<quality_a){
+	  BOOLEAN exp=FALSE;
+	  if(qc<=2)
+	    exp=TRUE;
+	  else {
+	    if (qc<quality_a/2)
+	      exp=TRUE;
+	    else
+	      if(erg.reduce_by<c->n/4)
+		exp=TRUE;
+	  }
+	  if (exp){
+	    poly clear_into;
+	    los[erg.to_reduce_u].flatten();
+	    kBucketClear(los[erg.to_reduce_u].bucket,&clear_into,&erg.expand_length);
+	    erg.expand=pCopy(clear_into);
+	    kBucketInit(los[erg.to_reduce_u].bucket,clear_into,erg.expand_length);
+	    PrintS("e");
+	    
+	  }
+	}
+
+	
+      }
+      
+      swap_roles=FALSE;
+      return;
+      }
+    
+  }
+  else{
+    if(erg.reduce_by>erg.to_reduce_u){
+      //then lm(rb)>= lm(tru) so =
+      assume(erg.reduce_by==erg.to_reduce_u+1);
+      int best=erg.reduce_by;
+      int quality_a=los[erg.reduce_by].guess_quality(c);
+      int qc;
+      best=find_best(los,erg.to_reduce_l,erg.to_reduce_u,qc,c);
+      
+      int i;
+      if(qc<quality_a){
+	  red_object h=los[erg.reduce_by];
+	  los[erg.reduce_by]=los[best];
+	  los[best]=h;
+	}
+	swap_roles=FALSE;
+	return;
+	
+	  
+    }
+    else
+    {
+      assume(!pLmEqual(los[erg.reduce_by].p,los[erg.to_reduce_l].p));
+      //further assume, that reduce_by is the above all other polys
+      //with same leading term
+      int il=erg.reduce_by;
+      int quality_a =los[erg.reduce_by].guess_quality(c);
+      int qc;
+      while((il>0) && pLmEqual(los[il-1].p,los[il].p)){
+	il--;
+	qc=los[il].guess_quality(c);
+	if (qc<quality_a){
+	  quality_a=qc;
+	  erg.reduce_by=il;
+	}
+      }
+      swap_roles=FALSE;
+    }
+  
+  }
+  if(swap_roles){
+    PrintS("b");
+    poly clear_into;
+    int dummy_len;
+    int new_length;
+    int bp=erg.to_reduce_u;//bucket_positon
+    //kBucketClear(los[bp].bucket,&clear_into,&new_length);
+    new_length=los[bp].clear_to_poly();
+    clear_into=los[bp].p;
+    poly p=c->strat->S[erg.reduce_by];
+    int j=erg.reduce_by;
+    int old_length=c->strat->lenS[j];// in view of S
+    los[bp].p=p;
+    kBucketInit(los[bp].bucket,p,old_length);
+    int qal=quality(clear_into,new_length,c);
+    int pos_in_c=-1;    
+    int z;
+    int new_pos;
+    new_pos=simple_posInS(c->strat,clear_into,qal,c->is_char0);
+    assume(new_pos<=j);
+    for (z=c->n;z;z--)
+    {
+      if(p==c->S->m[z-1])
+      {
+	pos_in_c=z-1;
+	break;
+      }
+    }
+    if(pos_in_c>=0)
+    {
+      c->S->m[pos_in_c]=clear_into;
+      c->lengths[pos_in_c]=new_length;
+      c_S_element_changed_hook(pos_in_c,c);
+    }
+    c->strat->S[j]=clear_into;
+    c->strat->lenS[j]=new_length;
+    if(c->strat->lenSw)
+      c->strat->lenS[j]=qal;
+    if(c->is_char0)
+    {
+      pContent(clear_into);
+      pCleardenom(clear_into);
+    }
+  else                     
+    pNorm(clear_into);
+    if (new_pos<j){
+      move_forward_in_S(j,new_pos,c->strat,c->is_char0);
+      erg.reduce_by=new_pos;
+    }
+  }
+}
+static void multi_reduction_find(red_object* los, int losl,calc_dat* c,int startf,find_erg & erg){
+  kStrategy strat=c->strat;
+
+  assume(startf<=losl);
+  assume((startf==losl-1)||(pLmCmp(los[startf].p,los[startf+1].p)==-1));
+  int i=startf;
+  
+  int j;
+  while(i>=0){
+    assume((i==losl-1)||(pLmCmp(los[i].p,los[i+1].p)<=0));
+    assume(is_valid_ro(los[i]));
+    j=kFindDivisibleByInS_easy(strat,los[i]);
+    if(j>=0){
+     
+      erg.to_reduce_u=i;
+      erg.reduce_by=j;
+      erg.fromS=TRUE;
+      int i2;
+      for(i2=i-1;i2>=0;i2--){
+	if(!pLmEqual(los[i].p,los[i2].p))
+	  break;
+      }
+      
+      erg.to_reduce_l=i2+1;
+      assume((i==losl-1)||(pLmCmp(los[i].p,los[i+1].p)==-1));
+      return;
+    }
+    if (j<0){
+      
+      //not reduceable, try to use this for reducing higher terms
+      int i2;
+      i2=i;
+      while((i2>0)&&(pLmEqual(los[i].p,los[i2-1].p)))
+	i2--;
+      if(i2!=i){
+	
+	erg.to_reduce_u=i-1;
+	erg.to_reduce_l=i2;
+	erg.reduce_by=i;
+	erg.fromS=FALSE;
+	assume((i==losl-1)||(pLmCmp(los[i].p,los[i+1].p)==-1));
+	return;
+      }
+ 
+      for (i2=i+1;i2<losl;i2++){
+	if (p_LmShortDivisibleBy(los[i].p,los[i].sev,los[i2].p,~los[i2].sev,
+				c->r)){
+	  int i3=i2;
+	  while((i3+1<losl) && (pLmEqual(los[i2].p, los[i3+1].p)))
+	    i3++;
+	  erg.to_reduce_u=i3;
+	  erg.to_reduce_l=i2;
+	  erg.reduce_by=i;
+	  erg.fromS=FALSE;
+	  assume((i==losl-1)||(pLmCmp(los[i].p,los[i+1].p)==-1));
+	  return;
+	}
+//	else {assume(!p_LmDivisibleBy(los[i].p, los[i2].p,c->r));}
+      }
+
+      i--;
+    }
+  }
+  erg.reduce_by=-1;//error code
+  return;
+}
+
+ //  nicht reduzierbare eintraege in ergebnisliste schreiben
+//   nullen loeschen
+//   while(finde_groessten leitterm reduzierbar(c,erg)){
+  
+static int multi_reduction_clear_zeroes(red_object* los, int  losl, int l, int u)
+{
+
+
+  int deleted=0;
+  int  i=l;
+  int last=-1;
+  while(i<=u)
+  {
+    
+    if(los[i].p==NULL){
+      kBucketDestroy(&los[i].bucket);
+//      delete los[i];//here we assume los are constructed with new
+      //destroy resources, must be added here   
+     if (last>=0)
+     {
+       memmove(los+(int)(last+1-deleted),los+(last+1),sizeof(red_object)*(i-1-last));
+     }
+     last=i;
+     deleted++;
+    }
+    i++;
+  }
+  if((last>=0)&&(last!=losl-1))
+      memmove(los+(int)(last+1-deleted),los+last+1,sizeof(red_object)*(losl-1-last));
+  return deleted;
+  
+}
+
+static void sort_region_down(red_object* los, int l, int u, calc_dat* c)
+{
+  qsort(los+l,u-l+1,sizeof(red_object),red_object_better_gen);
+  int i;
+
+  for(i=l;i<=u;i++)
+  {
+    BOOLEAN moved=FALSE;
+    int j;
+    for(j=i;j;j--)
+    {
+      if(pLmCmp(los[j].p,los[j-1].p)==-1){
+	red_object h=los[j];
+	los[j]=los[j-1];
+	los[j-1]=h;
+	moved=TRUE;
+      }
+      else break;
+    }
+    if(!moved) return;
+  }
+}
+
+//assume that los is ordered ascending by leading term, all non zero
+static void multi_reduction(red_object* los, int & losl, calc_dat* c)
+{
+  
+  //initialize;
+  assume(c->strat->sl>=0);
+  assume(losl>0);
+  int i;
+  for(i=0;i<losl;i++){
+    los[i].sev=pGetShortExpVector(los[i].p);
+//SetShortExpVector();
+    los[i].p=kBucketGetLm(los[i].bucket);
+  }
+
+  kStrategy strat=c->strat;
+  int curr_pos=losl-1;
+
+
+//  nicht reduzierbare einträge in ergebnisliste schreiben
+  // nullen loeschen
+  while(curr_pos>=0){
+    
+    find_erg erg;
+    multi_reduction_find(los, losl,c,curr_pos,erg);//last argument should be curr_pos
+   //  PrintS("\n erg:\n");
+//     Print("upper:%i\n",erg.to_reduce_u);
+//     Print("lower:%i\n",erg.to_reduce_l);
+//     Print("reduce_by:%i\n",erg.reduce_by);
+//     Print("fromS:%i\n",erg.fromS);
+    if(erg.reduce_by<0) break;
+
+
+
+    erg.expand=NULL;
+    int d=erg.to_reduce_u-erg.to_reduce_l+1;
+    //if ((!erg.fromS)&&(d>100)){
+    if (0){
+      PrintS("L");
+      if(!erg.fromS){
+	erg.to_reduce_u=max(erg.to_reduce_u,erg.reduce_by);
+	if (pLmEqual(los[erg.reduce_by].p,los[erg.to_reduce_l].p))
+	  erg.to_reduce_l=min(erg.to_reduce_l,erg.reduce_by);
+      }
+      int pn=erg.to_reduce_u+1-erg.to_reduce_l;
+      poly* p=(poly*) omalloc((pn)*sizeof(poly));
+      int i;
+      for(i=0;i<pn;i++){
+	int len;
+	los[erg.to_reduce_l+i].flatten();
+	kBucketClear(los[erg.to_reduce_l+i].bucket,&p[i],&len);
+	
+	redTailShort(p[i],c->strat);
+      }
+      pre_comp(p,pn,c);
+      int j;
+      for(j=0;j<pn;j++){
+	los[erg.to_reduce_l+j].p=p[j];
+	los[erg.to_reduce_l+j].sev=pGetShortExpVector(p[j]);
+	los[erg.to_reduce_l+j].sum=NULL;
+	int len=pLength(p[j]);
+	kBucketInit(los[erg.to_reduce_l+j].bucket,los[erg.to_reduce_l+j].p,len);
+      }
+      for(j=erg.to_reduce_l+pn;j<=erg.to_reduce_u;j++){
+	los[j].p=NULL;
+	
+      }
+
+      omfree(p);
+    }
+    else {
+    multi_reduction_lls_trick(los,losl,c,erg);
+    int sum=0;
+
+    
+    int i;
+    int len;
+    
+    multi_reduce_step(erg,los,c);
+    }
+//     reduction_step *rs=create_reduction_step(erg, los, c);
+//     rs->reduce(los,erg.to_reduce_l,erg.to_reduce_u);
+//     finalize_reduction_step(rs);
+		 
+    int deleted=multi_reduction_clear_zeroes(los, losl, erg.to_reduce_l, erg.to_reduce_u);
+    curr_pos=erg.to_reduce_u;
+    losl -= deleted;
+    curr_pos -= deleted;
+
+    //Print("deleted %i \n",deleted);
+    sort_region_down(los, erg.to_reduce_l, erg.to_reduce_u-deleted, c);
+//   sort_region_down(los, 0, losl-1, c);
+    //  qsort(los,losl,sizeof(red_object),red_object_better_gen);
+    if(erg.expand)
+      add_to_reductors(c,erg.expand,erg.expand_length);
+  }
+  return;
+}
+void red_object::flatten(){
+  if (sum!=NULL)
+  {
+
+ 
+    if(kBucketGetLm(sum->ac->bucket)!=NULL){
+      number mult_my=n_Mult(sum->c_my,sum->ac->multiplied,currRing);
+      poly add_this;
+      if(!nIsOne(mult_my))
+	kBucket_Mult_n(bucket,mult_my);
+      int len;
+      poly clear_into;
+      kBucketClear(sum->ac->bucket,&clear_into,&len);
+      if(sum->ac->counter>1){
+	add_this=pCopy(clear_into);
+	kBucketInit(sum->ac->bucket,clear_into,len);
+      }
+      else
+	add_this=clear_into;
+      pMult_nn(add_this, sum->c_ac);
+      
+      kBucket_Add_q(bucket,add_this, &len);
+       nDelete(&mult_my);
+     
+    }
+    nDelete(&sum->c_ac);
+    nDelete(&sum->c_my);
+   
+    sum->ac->decrease_counter();
+    delete sum;
+    p=kBucketGetLm(bucket);
+    sum=NULL;
+  }
+  assume(p==kBucketGetLm(bucket));
+  assume(sum==NULL);
+}
+void red_object::validate(){
+  BOOLEAN flattened=FALSE;
+  if(sum!=NULL)
+  {
+    poly lm=kBucketGetLm(bucket);
+    poly lm_ac=kBucketGetLm(sum->ac->bucket);
+    if ((lm_ac==NULL)||((lm!=NULL) && (pLmCmp(lm,lm_ac)!=-1))){
+      flatten();
+      assume(sum==NULL);
+      flattened=TRUE;
+      p=kBucketGetLm(bucket);
+      if (p!=NULL)
+	sev=pGetShortExpVector(p);
+    } 
+    else
+    {
+ 
+      p=lm_ac;
+      assume(sum->ac->sev==pGetShortExpVector(p));
+      sev=sum->ac->sev;
+    }
+    
+  }
+  else{
+    p=kBucketGetLm(bucket);
+    if(p)
+    sev=pGetShortExpVector(p);
+  }
+  assume((sum==NULL)||(kBucketGetLm(sum->ac->bucket)!=NULL));
+}
+int red_object::clear_to_poly(){
+  flatten();
+  int l;
+  kBucketClear(bucket,&p,&l);
+  return l;
+}
+
+  
+
+void red_object::adjust_coefs(number c_r, number c_ac_r){
+  assume(this->sum!=NULL);
+  number n1=nMult(sum->c_my, c_ac_r);
+  number n2=nMult(sum->c_ac,c_r);
+  nDelete(&sum->c_my);
+  nDelete(&sum->c_ac);
+ 
+  int ct = ksCheckCoeff(&n1, &n2);
+  sum->c_my=n1;
+  sum->c_ac=nNeg(n2);
+  nDelete(&n2);
+  
+
+}
+int red_object::guess_quality(calc_dat* c){
+    //works at the moment only for lenvar 1, because in different
+    //case, you have to look on coefs
+    int s=0;
+    if (c->is_char0)
+      s=kSBucketLength(bucket);
+    else 
+      s=bucket_guess(bucket);
+    if (sum!=NULL){
+      if (c->is_char0)
+      s+=kSBucketLength(sum->ac->bucket);
+    else 
+      s+=bucket_guess(sum->ac->bucket);
+    }
+    return s;
+}
+void reduction_step::reduce(red_object* r, int l, int u){}
+void simple_reducer::target_is_no_sum_reduce(red_object & ro){
+  kBucketPolyRed(ro.bucket,p,
+		 p_len,
+		 c->strat->kNoether);
+}
+
+void simple_reducer::target_is_a_sum_reduce(red_object & ro){
+  pTest(p);
+  kbTest(ro.bucket);
+  kbTest(ro.sum->ac->bucket);
+  assume(ro.sum!=NULL);
+  assume(ro.sum->ac!=NULL);
+  if(ro.sum->ac->last_reduction_id!=reduction_id){
+    number n1=kBucketPolyRed(ro.sum->ac->bucket,p, p_len, c->strat->kNoether);
+    number n2=nMult(n1,ro.sum->ac->multiplied);
+    nDelete(&ro.sum->ac->multiplied);
+    nDelete(&n1);
+    ro.sum->ac->multiplied=n2;
+    poly lm=kBucketGetLm(ro.sum->ac->bucket);
+    if (lm)
+      ro.sum->ac->sev=pGetShortExpVector(lm);
+    ro.sum->ac->last_reduction_id=reduction_id;
+  }
+  ro.sev=ro.sum->ac->sev;
+  ro.p=kBucketGetLm(ro.sum->ac->bucket);
+}
+void simple_reducer::reduce(red_object* r, int l, int u){
+  this->pre_reduce(r,l,u);
+  int i;
+//debug start
+  int im;
+//  for(im=l;im<=u;im++)
+  //  assume(is_valid_ro(r[im]));
+  
+
+//debug end
+
+  for(i=l;i<=u;i++){
+  
+
+    if(r[i].sum==NULL)
+      this->target_is_no_sum_reduce(r[i]);
+
+    else 
+    {
+      this->target_is_a_sum_reduce(r[i]);
+      //reduce and adjust multiplied
+      r[i].sum->ac->last_reduction_id=reduction_id;
+      
+    }
+    //most elegant would be multimethods at this point and subclassing
+    //red_object for sum
+ 
+  }
+  for(i=l;i<=u;i++){
+    r[i].validate();
+    #ifdef TGB_DEBUG
+    if (r[i].sum) r[i].sev=r[i].sum->ac->sev;
+
+    #endif
+      }
+}
+reduction_step::~reduction_step(){}
+simple_reducer::~simple_reducer(){
+  if(fill_back!=NULL)
+  {
+    kBucketInit(fill_back,p,p_len);
+  }
+  fill_back=NULL;
+    
+}
+ join_simple_reducer::~join_simple_reducer(){
+   if(fill_back!=NULL)
+   {
+     kBucketInit(fill_back,p,p_len);
+   }
+   fill_back=NULL;
+    
+}
+void multi_reduce_step(find_erg & erg, red_object* r, calc_dat* c){
+  static int id=0;
+  id++;
+
+  int rn=erg.reduce_by;
+  poly red;
+  int red_len;
+  simple_reducer* pointer;
+  BOOLEAN woc=FALSE;
+  if(erg.fromS){
+    red=c->strat->S[rn];
+    red_len=c->strat->lenS[rn];
+    
+  }
+  else
+  {
+    r[rn].flatten();
+    kBucketClear(r[rn].bucket,&red,&red_len);
+  }
+  if (erg.to_reduce_u-erg.to_reduce_l>5){
+    woc=TRUE;
+    poly m=pOne();
+    for(int i=1;i<=pVariables;i++)
+      pSetExp(m,i,(pGetExp(r[erg.to_reduce_l].p, i)-pGetExp(red,i)));
+    pSetm(m);
+    poly red_cp=ppMult_mm(red,m);
+    
+    if(!erg.fromS){
+      kBucketInit(r[rn].bucket,red,red_len);
+    }
+    //now reduce the copy
+    //static poly redNF2 (poly h,calc_dat* c , int &len, number&  m,int n)
+    redTailShort(red_cp,c->strat);
+    //number mul;
+    // red_len--;
+//     red_cp->next=redNF2(red_cp->next,c,red_len,mul,c->average_length);
+//     pSetCoeff(red_cp,nMult(red_cp->coef,mul));
+//     nDelete(&mul);
+//     red_len++;
+    red=red_cp;
+    red_len=pLength(red);
+    pDelete(&m);
+    
+  }
+  int i;
+
+
+  int red_c=0;
+  if(red_len>2*c->average_length){
+    for(i=erg.to_reduce_l;i<=erg.to_reduce_u;i++){
+      if((r[i].sum==NULL) ||(r[i].sum->ac->counter<=AC_FLATTEN)) red_c++;
+    }
+  }
+  if (red_c>=AC_NEW_MIN)
+    pointer=new join_simple_reducer(red,red_len,r[erg.to_reduce_l].p);
+  else
+    pointer=new simple_reducer(red,red_len,c);
+
+  if ((!woc) && (!erg.fromS))
+    pointer->fill_back=r[rn].bucket;
+  else
+    pointer->fill_back=NULL;
+  pointer->reduction_id=id;
+  pointer->c=c;
+
+  pointer->reduce(r,erg.to_reduce_l, erg.to_reduce_u);
+  if(woc) pDelete(&pointer->p);
+  delete pointer;
+  
+};
+
+void join_simple_reducer::target_is_no_sum_reduce(red_object & ro){
+  
+  ro.sum=new formal_sum_descriptor();
+  ro.sum->ac=ac;
+  ac->counter++;
+  kBucket_pt bucket=ro.bucket;
+  poly a1 = pNext(p), lm = kBucketExtractLm(bucket);
+  BOOLEAN reset_vec=FALSE;
+  number rn;
+  assume(a1!=NULL);
+  number an = pGetCoeff(p), bn = pGetCoeff(lm);
+  lm->next=NULL;
+  int ct = ksCheckCoeff(&an, &bn);
+  ro.sum->c_ac=nNeg(bn);
+  ro.sum->c_my=an;
+  assume(nIsZero(nAdd(nMult(ro.sum->c_my,lm->coef),nMult(p->coef,ro.sum->c_ac) )));
+  if (p_GetComp(p, bucket->bucket_ring) != p_GetComp(lm, bucket->bucket_ring))
+  {
+    p_SetCompP(a1, p_GetComp(lm, bucket->bucket_ring), bucket->bucket_ring);
+    reset_vec = TRUE;
+    p_SetComp(lm, p_GetComp(p, bucket->bucket_ring), bucket->bucket_ring);
+    p_Setm(lm, bucket->bucket_ring);
+  }
+
+
+  
+
+  p_DeleteLm(&lm, bucket->bucket_ring);
+  if (reset_vec) p_SetCompP(a1, 0, bucket->bucket_ring);
+  kbTest(bucket);
+
+}
+
+  reduction_accumulator::reduction_accumulator(poly p, int p_len, poly high_to){
+    //sev needs to be removed from interfaces,makes no sense
+    
+    degbound(p);
+    degbound(p->next);
+    degbound(high_to);
+    poly my=pOne();
+    counter=0;
+   
+    for(int i=1;i<=pVariables;i++)
+      pSetExp(my,i,(pGetExp(high_to, i)-pGetExp(p,i)));
+    degbound(my);
+   
+   
+    pSetm(my);
+    last_reduction_id=-1;
+    multiplied=nInit(1);
+    bucket=kBucketCreate(currRing);
+    poly a=pMult_mm(pCopy(p->next),my);
+    degbound(a);
+    this->sev=pGetShortExpVector(a);
+    kBucketInit(bucket, a,p_len-1);
+    pDelete(&my);
+  }
+void simple_reducer:: pre_reduce(red_object* r, int l, int u){}
+void join_simple_reducer:: pre_reduce(red_object* r, int l, int u){
+  for(int i=l;i<=u;i++)
+    {
+      if (r[i].sum){
+	if(r[i].sum->ac->counter<=AC_FLATTEN) r[i].flatten();
+	
+      }
+    }
+}
Index: kernel/tgb.h
===================================================================
--- kernel/tgb.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/tgb.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,229 @@
+#ifndef TGB_H
+#define TGB_H
+
+#include "mod2.h"
+#include <omalloc.h>
+#include "p_polys.h"
+
+#include "ideals.h"
+#include "ring.h"
+#include "febase.h"
+#include "structs.h"
+#include "polys.h"
+#include "stdlib.h"
+
+
+#include "kutil.h"
+#include "kInline.cc"
+#include "kstd1.h"
+#include "kbuckets.h"
+//#define TGB_DEBUG
+#define FULLREDUCTIONS
+#define HANS_IDEA
+//#define HALFREDUCTIONS
+//#define HEAD_BIN
+//#define HOMOGENEOUS_EXAMPLE
+#define REDTAIL_S
+#define PAR_N 100
+#define AC_NEW_MIN 2
+#define AC_FLATTEN 1
+//#define REDTAIL_PROT
+//#define QUICK_SPOLY_TEST
+struct sorted_pair_node{
+  //criterium, which is stable 0. small lcm 1. small i 2. small j
+  int i;
+  int j;
+  int deg;
+  int expected_length;
+  poly lcm_of_lm;
+};
+
+ideal t_rep_gb(ring r,ideal arg_I, ideal arg_debug_Ideal=NULL);
+static ideal debug_Ideal;
+/** 
+    reduction_accumulators are objects which are shared by several sums
+ **/
+
+class reduction_accumulator{
+  
+ public:
+  /// (1/multiplied)*bucket=reduced original data
+  number multiplied;
+  ///the polynomial data
+  kBucket_pt bucket;
+  /// the short exponent vector
+  unsigned long sev;
+  /// the reference counter
+  int counter;
+  /// decrease the reference counter, at 0 it deletes the object
+  void decrease_counter(){ 
+    if((--counter)==0)
+      {
+	delete this; //self destruction
+      }
+  }
+  int last_reduction_id;
+  reduction_accumulator(poly p, int p_len, poly high_to);
+  ~reduction_accumulator(){
+    nDelete(&multiplied);
+    kBucketDeleteAndDestroy(&bucket);
+  }  
+
+  
+};
+struct formal_sum_descriptor{
+  number c_my;
+  number c_ac;
+  reduction_accumulator* ac;
+};
+struct int_pair_node{
+  int_pair_node* next;
+  int a;
+  int b;
+};
+struct calc_dat
+{
+  int* rep;
+  char** states;
+  ideal S;
+  ring r;
+  int* lengths;
+  long* short_Exps;
+  kStrategy strat;
+  int* T_deg;
+  poly* gcd_of_terms;
+  int_pair_node* soon_free;
+  sorted_pair_node** apairs;
+#ifdef HEAD_BIN
+  struct omBin_s*   HeadBin;
+#endif
+  unsigned int reduction_steps;
+  int n;
+  int normal_forms;
+  int current_degree;
+  int Rcounter;
+  int last_index;
+  int max_pairs;
+  int pair_top;
+  int easy_product_crit;
+  int extended_product_crit;
+  int average_length;
+  BOOLEAN is_char0;
+};
+class red_object{
+ public:
+  kBucket_pt bucket;
+  poly p;
+  formal_sum_descriptor* sum;
+  unsigned long sev;
+  void flatten();
+  void validate();
+  void adjust_coefs(number c_r, number c_ac_r);
+  int guess_quality(calc_dat* c);
+  int clear_to_poly();
+  void canonicalize();
+};
+
+
+enum calc_state
+  {
+    UNCALCULATED,
+    HASTREP,
+    UNIMPORTANT,
+    SOONTREP
+  };
+
+static int add_to_reductors(calc_dat* c, poly h, int len);
+static int bucket_guess(kBucket* bucket);
+static poly redNFTail (poly h,const int sl,kStrategy strat, int len);
+static poly redNF2 (poly h,calc_dat* c , int &len, number&  m,int n=0);
+static void free_sorted_pair_node(sorted_pair_node* s, ring r);
+static void shorten_tails(calc_dat* c, poly monom);
+static void replace_pair(int & i, int & j, calc_dat* c);
+static sorted_pair_node** add_to_basis(poly h, int i, int j,calc_dat* c, int* ip=NULL);
+static void do_this_spoly_stuff(int i,int j,calc_dat* c);
+//ideal t_rep_gb(ring r,ideal arg_I);
+static BOOLEAN has_t_rep(const int & arg_i, const int & arg_j, calc_dat* state);
+static int* make_connections(int from, poly bound, calc_dat* c);
+static int* make_connections(int from, int to, poly bound, calc_dat* c);
+static void now_t_rep(const int & arg_i, const int & arg_j, calc_dat* c);
+static void soon_t_rep(const int & arg_i, const int & arg_j, calc_dat* c);
+static int pLcmDeg(poly a, poly b);
+static int simple_posInS (kStrategy strat, poly p,int len, BOOLEAN is_char0);
+static BOOLEAN find_next_pair(calc_dat* c, BOOLEAN go_higher=TRUE);
+
+static sorted_pair_node* pop_pair(calc_dat* c);
+static BOOLEAN no_pairs(calc_dat* c);
+static void clean_top_of_pair_list(calc_dat* c);
+static void super_clean_top_of_pair_list(calc_dat* c);
+static BOOLEAN state_is(calc_state state, const int & i, const int & j, calc_dat* c);
+static BOOLEAN pair_better(sorted_pair_node* a,sorted_pair_node* b, calc_dat* c);
+static int pair_better_gen(const void* ap,const void* bp);
+static poly redTailShort(poly h, kStrategy strat);
+static poly gcd_of_terms(poly p, ring r);
+static BOOLEAN extended_product_criterion(poly p1, poly gcd1, poly p2, poly gcd2, calc_dat* c);
+static poly kBucketGcd(kBucket* b, ring r);
+static void multi_reduction(red_object* los, int & losl, calc_dat* c);
+static sorted_pair_node* quick_pop_pair(calc_dat* c);
+static sorted_pair_node* top_pair(calc_dat* c);
+static int quality(poly p, int len, calc_dat* c);
+/**
+   makes on each red_object in a region a single_step
+ **/
+class reduction_step{
+ public:
+  /// we assume hat all occuring red_objects have same lm, and all
+  /// occ. lm's in r[l...u] are the same, only reductor does not occur
+  virtual void reduce(red_object* r, int l, int u);
+  //int reduction_id;
+  virtual ~reduction_step();
+  calc_dat* c;
+  int reduction_id;
+};
+class simple_reducer:public reduction_step{
+ public:
+  poly p;
+  kBucket_pt fill_back;
+  int p_len;
+  simple_reducer(poly p, int p_len, calc_dat* c =NULL){
+    this->p=p;
+    this->p_len=p_len;
+    this->c=c;
+  }
+  virtual void pre_reduce(red_object* r, int l, int u);
+  virtual void reduce(red_object* r, int l, int u);
+  ~simple_reducer();
+
+  virtual void target_is_a_sum_reduce(red_object & ro);
+  virtual void target_is_no_sum_reduce(red_object & ro);
+};
+class join_simple_reducer:public simple_reducer{
+ public:
+  join_simple_reducer(poly p, int p_len, poly high_to):simple_reducer(p,p_len){
+    ac=new reduction_accumulator( p, p_len, high_to);
+   
+    
+  }
+    ~join_simple_reducer();
+   void pre_reduce(red_object* r, int l, int u);
+  void target_is_no_sum_reduce(red_object & ro);
+  reduction_accumulator* ac;
+};
+//class sum_canceling_reducer:public reduction_step {
+//  void reduce(red_object* r, int l, int u);
+//};
+struct find_erg{
+  poly expand;
+  int expand_length;
+  int to_reduce_u;
+  int to_reduce_l;
+  int reduce_by;//index of reductor
+  BOOLEAN fromS;//else from los
+
+};
+
+static void multi_reduce_step(find_erg & erg, red_object* r, calc_dat* c);
+void finalize_reduction_step(reduction_step* r){
+  delete r;
+}
+#endif
Index: kernel/timer.cc
===================================================================
--- kernel/timer.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/timer.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,254 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: timer.cc,v 1.1.1.1 2003-10-06 12:16:04 Singular Exp $ */
+
+/*
+*  ABSTRACT - get the computing time
+*/
+
+#include "mod2.h"
+
+//the mpw timer is quite the same as the dos timer:
+#ifdef __MWERKS__
+#define MSDOS
+#endif
+
+int        timerv = 0;
+static double timer_resolution = TIMER_RESOLUTION;
+
+static double mintime = 0.5;
+
+void SetTimerResolution(int res)
+{
+  timer_resolution = (double) res;
+}
+
+void SetMinDisplayTime(double mtime)
+{
+  mintime = mtime;
+}
+
+
+#ifndef MSDOS
+
+/*tested on HP9000/700, HP9000/300, Linux 0.99, SUN Sparc*/
+#include <stdio.h>
+#include <math.h>
+#include <unistd.h>
+#include <float.h>
+#include <mylimits.h>
+#include <sys/types.h>
+
+#ifdef TIME_WITH_SYS_TIME
+# include <time.h>
+# ifdef HAVE_SYS_TIME_H
+#   include <sys/time.h>
+# endif
+#else
+# ifdef HAVE_SYS_TIME_H
+#   include <sys/time.h>
+# else
+#   include <time.h>
+# endif
+#endif
+#ifdef HAVE_SYS_TIMES_H
+#include <sys/times.h>
+#endif
+
+
+// need to be adjusted on your machine: the number of ticks per second: HZ
+#ifndef HZ
+#include <sys/param.h>
+#endif
+#if !defined(HZ) && defined(CLOCKS_PER_SEC)
+#define HZ CLOCKS_PER_SEC
+#endif
+#if !defined(HZ) && defined(CLK_TCK)
+#define HZ CLK_TCK
+#endif
+#ifndef HZ
+#ifdef sun
+#define HZ 60.0
+#else
+#define HZ 100.0
+#endif
+#endif
+
+#include "timer.h"
+#include "febase.h"
+/*3
+* the start time of the timer
+*/
+static clock_t startl;
+static clock_t siStartTime;
+
+/*3
+* temp structure to get the time
+*/
+static struct tms t_rec;
+
+/*0 implementation*/
+
+int initTimer()
+{
+  times(&t_rec);
+  siStartTime = t_rec.tms_utime+t_rec.tms_stime;
+  return (int)time(NULL);
+}
+
+void startTimer()
+{
+  times(&t_rec);
+  startl = t_rec.tms_utime+t_rec.tms_stime;
+}
+
+/*2
+* returns the time since a fixed point in seconds
+*/
+int getTimer()
+{
+  clock_t curr;
+
+  times(&t_rec);
+  curr = t_rec.tms_utime+t_rec.tms_stime - siStartTime;
+
+  double f =  ((double)curr) * timer_resolution / (double)HZ;
+  return (int)(f+0.5);
+}
+
+/*2
+* stops timer, writes string s and the time since last call of startTimer
+* if this time is > mintime sec
+*/
+void writeTime(char* v)
+{
+  clock_t curr;
+
+  times(&t_rec);
+  curr = t_rec.tms_utime+t_rec.tms_stime - startl;
+
+  double f =  ((double)curr) / (double)HZ;
+  if (f > mintime)
+    Print("//%s %.2f sec\n" ,v ,f);
+}
+
+#ifdef HAVE_RTIMER
+/*0 Real timer implementation*/
+int rtimerv = 0;
+static struct timeval  startRl;
+static struct timeval  siStartRTime;
+static struct timezone tzp;
+void initRTimer()
+{
+  gettimeofday(&startRl, &tzp);
+  gettimeofday(&siStartRTime, &tzp);
+}
+
+void startRTimer()
+{
+  gettimeofday(&siStartRTime, &tzp);
+}
+
+/*2
+* returns the time since a fixed point in resolutions
+*/
+int getRTimer()
+{
+  struct timeval now;
+
+  gettimeofday(&now, &tzp);
+
+  if (startRl.tv_usec > now.tv_usec)
+  {
+    now.tv_usec += 1000000;
+    now.tv_sec --;
+  }
+
+  double f =((double)  (now.tv_sec - startRl.tv_sec))*timer_resolution +
+    ((double) (now.tv_usec - startRl.tv_usec))*timer_resolution /
+    (double) 1000000;
+
+  return (int)(f+0.5);
+}
+
+/*2
+* stops timer, writes string s and the time since last call of startTimer
+* if this time is > mintime
+*/
+void writeRTime(char* v)
+{
+  struct timeval now;
+
+  gettimeofday(&now, &tzp);
+
+  if (siStartRTime.tv_usec > now.tv_usec)
+  {
+    now.tv_usec += 1000000;
+    now.tv_sec --;
+  }
+
+  double f =((double)  (now.tv_sec - siStartRTime.tv_sec)) +
+    ((double) (now.tv_usec - siStartRTime.tv_usec)) /
+    (double) 1000000;
+
+  if (f > mintime)
+   Print("//%s %.2f sec \n" ,v ,f);
+}
+#endif
+
+#else /* #defined MSDOS */
+
+/*tested on MSDOS-GCC, Macintosh*/
+#include <time.h>
+#include <stdio.h>
+#include <math.h>
+#include <float.h>
+
+#include "timer.h"
+#include "febase.h"
+
+/*3
+* the start time of the timer
+*/
+static clock_t startl;
+static clock_t siStartTime;
+
+/*2
+* starts the timer; used with getTime
+*/
+int initTimer()
+{
+  siStartTime = clock();
+  return (int)siStartTime;
+}
+
+/*2
+* starts the timer; used with writeTime
+*/
+void startTimer()
+{
+  startl = clock();
+}
+
+/*2
+* returns the time since a fixed point in seconds
+*/
+int getTimer()
+{
+  clock_t curr = clock() - siStartTime;
+  double f =  ((double)curr)*timer_resolution/ (double)CLOCKS_PER_SEC;
+  return (int)(f+0.5);
+}
+/*2
+* stops timer, writes string s and the time since last call of startTimer
+* if this time is > 0.5 sec
+*/
+void writeTime(void* v)
+{
+  clock_t curr = clock() - startl;
+  double f =  ((double)curr) / CLOCKS_PER_SEC;
+  if (f > mintime)
+    Print("//%s %.1f sec\n" ,v ,f);
+}
+#endif /* MSDOS */
Index: kernel/timer.h
===================================================================
--- kernel/timer.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/timer.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,31 @@
+#ifndef TIMER_H
+#define TIMER_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+*  ABSTRACT - get the computing time
+*/
+/* $Id: timer.h,v 1.1.1.1 2003-10-06 12:16:04 Singular Exp $ */
+
+extern int timerv;
+void startTimer(void);
+void writeTime(char* s);
+
+int initTimer();
+int  getTimer();
+
+#ifdef HAVE_RTIMER
+extern int rtimerv;
+void startRTimer(void);
+void writeRTime(char* s);
+
+void initRTimer();
+int  getRTimer();
+#endif
+
+void SetTimerResolution(int res);
+void SetMinDisplayTime(double mtime);
+
+#endif
+
Index: kernel/units.cc
===================================================================
--- kernel/units.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/units.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,77 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/* $Id: units.cc,v 1.1.1.1 2003-10-06 12:16:04 Singular Exp $ */
+/*
+* ABSTRACT: procedures to compute with units
+*/
+
+#include "mod2.h"
+#include "structs.h"
+#include "febase.h"
+#include "numbers.h"
+#include "polys.h"
+#include "ideals.h"
+#include "intvec.h"
+#include "matpol.h"
+#include "kstd1.h"
+#include "units.h"
+
+ideal redNF(ideal N,ideal M,matrix U,int d,intvec *w)
+{
+  matrix U0=NULL;
+  if(U!=NULL)
+  {
+    U0=mpCopy(U);
+    number u0;
+    for(int i=IDELEMS(M)-1;i>=0;i--)
+    {
+      u0=nInvers(pGetCoeff(MATELEM(U0,i+1,i+1)));
+      MATELEM(U0,i+1,i+1)=pMult_nn(MATELEM(U0,i+1,i+1),u0);
+      M->m[i]=pMult_nn(M->m[i],u0);
+    }
+  }
+  ideal M0=idInit(IDELEMS(M),M->rank);
+  ideal M1=kNF(N,currQuotient,M,0,2);
+  while(idElem(M1)>0&&(d==-1||idMinDegW(M1,w)<=d))
+  {
+    for(int i=IDELEMS(M)-1;i>=0;i--)
+    {
+      M0->m[i]=pAdd(M0->m[i],pHead(pCopy(M1->m[i])));
+      if(U0!=NULL)
+        M->m[i]=pSub(M->m[i],pMult(pHead(pCopy(M1->m[i])),
+                                   pCopy(MATELEM(U0,i+1,i+1))));
+      else
+        M->m[i]=pSub(M->m[i],pHead(pCopy(M1->m[i])));
+    }
+    idDelete(&M1);
+    M1=kNF(N,currQuotient,M,0,2);
+  }
+  idDelete(&M1);
+  idDelete(&N);
+  idDelete(&M);
+  if(U0!=NULL)
+    idDelete((ideal*)&U0);
+  return M0;
+}
+
+poly redNF(ideal N,poly p,poly u,int d,intvec *w)
+{
+  ideal M=idInit(1,pGetComp(p));
+  M->m[0]=p;
+  ideal M0;
+  if(u==NULL)
+    M0=redNF(N,M,NULL,d,w);
+  else
+  {
+    matrix U=mpNew(1,1);
+    MATELEM(U,1,1)=u;
+    M0=redNF(N,M,U,d,w);
+    idDelete((ideal*)&U);
+  }
+  poly p0=M0->m[0];
+  M0->m[0]=NULL;
+  idDelete(&M0);
+  return p0;
+}
+
Index: kernel/units.h
===================================================================
--- kernel/units.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/units.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,15 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: units.h,v 1.1.1.1 2003-10-06 12:16:04 Singular Exp $ */
+/*
+* ABSTRACT: procedures to compute with units
+*/
+
+#ifndef UNITS_H
+#define UNITS_H
+
+ideal redNF(ideal N,ideal M,matrix U=NULL,int d=-1,intvec *w=NULL);
+poly redNF(ideal N,poly p,poly u=NULL,int d=-1,intvec *w=NULL);
+
+#endif
Index: kernel/version.h
===================================================================
--- kernel/version.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/version.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1 @@
+#define feVersionId  2003092617
Index: kernel/walk.cc
===================================================================
--- kernel/walk.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/walk.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,1332 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/* $Id: walk.cc,v 1.1.1.1 2003-10-06 12:16:04 Singular Exp $ */
+/*
+* ABSTRACT: Implementation of the Groebner walk
+*/
+
+/* includes */
+#include "mod2.h"
+#include "walk.h"
+#include "polys.h"
+#include "ideals.h"
+#include "intvec.h"
+#include "ipid.h"
+#include "tok.h"
+#include <omalloc.h>
+#include "febase.h"
+#include "numbers.h"
+#include "ipid.h"
+#include "ring.h"
+#include "kstd1.h"
+#include "matpol.h"
+#include "weight.h"
+#include "intvec.h"
+#include "syz.h"
+#include "lists.h"
+#include "prCopy.h"
+#include <string.h>
+#include "structs.h"
+#include "longalg.h"
+#ifdef HAVE_FACTORY
+#include "clapsing.h"
+#endif
+
+static void* idString(ideal L)
+{
+  int i;
+  printf("//ideal Itmp: ");
+  for(i=0; i<IDELEMS(L); i++)
+    printf(" %s, ", pString(L->m[i]));
+  printf("\n");
+}
+
+
+// returns gcd of integers a and b
+static inline long gcd(const long a, const long b)
+{
+  long r, p0 = a, p1 = b;
+  //assume(p0 >= 0 && p1 >= 0);
+  if(p0 < 0)
+    p0 = -p0;
+
+  if(p1 < 0)
+    p1 = -p1;
+  while(p1 != 0)
+  {
+    r = p0 % p1;
+    p0 = p1;
+    p1 = r;
+  }
+  return p0;
+}
+
+// cancel gcd of integers zaehler and nenner
+static inline void cancel(long &zaehler, long &nenner)
+{
+  assume(zaehler >= 0 && nenner > 0);
+  long g = gcd(zaehler, nenner);
+  if (g > 1)
+  {
+    zaehler = zaehler / g;
+    nenner = nenner / g;
+  }
+}
+
+/********************************************************************
+ * compute a weight degree of a monomial p w.r.t. a weight_vector   *
+ ********************************************************************/
+static inline int MLmWeightedDegree(const poly p, intvec* weight)
+{
+  int i, d = 0;
+
+  for (i=1; i<=pVariables; i++)
+    d += pGetExp(p, i) * (*weight)[i-1];
+
+  return d;
+}
+
+/********************************************************************
+ * compute a weight degree of a polynomial p w.r.t. a weight_vector *
+ ********************************************************************/
+static inline int MwalkWeightDegree(poly p, intvec* weight_vector)
+{
+  assume(weight_vector->length() >= pVariables);
+  int max = 0, maxtemp;
+  poly hp;
+
+  while(p != NULL)
+  {
+    hp = pHead(p);
+    pIter(p);
+    maxtemp = MLmWeightedDegree(hp, weight_vector);
+
+    if (maxtemp > max)
+      max = maxtemp;
+  }
+  return max;
+}
+
+/*****************************************************************************
+ * return an initial form of the polynom g w.r.t. a weight vector curr_weight *
+ *****************************************************************************/
+static poly MpolyInitialForm(poly g, intvec* curr_weight)
+{
+  if(g == NULL)
+    return g;
+
+  int maxtmp, max = 0;
+  poly in_w_g = NULL, hg;
+
+  while(g != NULL)
+  {
+    hg = pHead(g);
+    pIter(g);
+    maxtmp = MwalkWeightDegree(hg, curr_weight);
+
+    if(maxtmp > max)
+    {
+      max = maxtmp;
+      in_w_g = hg;
+    } else {
+      if(maxtmp == max)
+	in_w_g = pAdd(in_w_g, hg);
+    }
+  }
+  return in_w_g;
+}
+
+
+/*****************************************************************************
+ * compute the initial form of an ideal "G" w.r.t. weight vector curr_weight *
+ ****************************************************************************/
+ideal MwalkInitialForm(ideal G, intvec* curr_weight)
+{
+  int i;
+  int nG = IDELEMS(G);
+  ideal Gomega  = idInit(nG, G->rank);
+
+  for(i=0; i<nG; i++)
+    Gomega->m[i] = MpolyInitialForm(G->m[i], curr_weight);
+
+  //return Gomega;
+  ideal result = idCopy(Gomega);
+  idDelete(&Gomega);
+  return result;
+}
+
+/************************************************************************
+ * test that does the weight vector iv exist in the cone of the ideal G *
+ *            i.e. does in(in_w(g)) =? in(g), for all g in G            *
+ ************************************************************************/
+void* test_w_in_Cone(ideal G, intvec* iv)
+{
+  int nG = IDELEMS(G);
+  int i;
+  BOOLEAN ok = TRUE;
+  poly mi, in_mi,  gi;
+  for(i=0; i<nG; i++)
+  {
+    mi = MpolyInitialForm(G->m[i], iv);
+    in_mi = pHead(mi);
+    gi = pHead(G->m[i]);
+    if(pEqualPolys(in_mi, gi) != ok)
+    {
+      printf("//ring Test_W_in_Cone = %s ;\n", rString(currRing));
+      printf("//the computed next weight vector doesn't exist in the cone\n");
+      break;
+    }
+  }
+}
+
+//compute a least common multiple of two integers
+static inline long Mlcm(long &i1, long &i2)
+{
+  long temp = gcd(i1, i2);
+  return ((i1*i2) / temp);
+}
+
+
+/***************************************************
+ * return  the dot product of two intvecs a and b  *
+ ***************************************************/
+static inline long  MivDotProduct(intvec* a, intvec* b)
+{
+  assume( a->length() ==  b->length());
+  int i, n = a->length();
+  long result = 0;
+
+  for(i=0; i<n; i++)
+    result += (*a)[i] * (*b)[i];
+
+  return result;
+}
+
+
+/**21.10.00*******************************************
+ * return the "intvec" lead exponent of a polynomial *
+ *****************************************************/
+static intvec* MExpPol(poly f)
+{
+  int nR = currRing->N;
+
+  intvec* result = new intvec(nR);
+  int i;
+
+  for(i=0; i<nR; i++)
+    (*result)[i] = pGetExp(f,i+1);
+
+  intvec *res = ivCopy(result);
+  omFree((ADDRESS) result);
+  return res;
+}
+
+
+/***23-24.10.00******************************************
+ * compute a division of two monoms, "a" by a monom "b" *
+ *    i.e. leading term of two polynoms a and b         *
+ ********************************************************/
+static poly MpDiv(poly a, poly b)
+{
+  assume (b != NULL);
+  BOOLEAN ok = TRUE;
+
+  if(a == NULL)
+    return a;
+
+  int nR = currRing->N;
+
+  number nn = (number) omAllocBin(rnumber_bin);
+
+  poly  ptmp, ppotenz;
+  poly result = pISet(1);
+
+  intvec* iva = MExpPol(a);  //head exponent of a
+  intvec* ivb = MExpPol(b);  //head exponent of a
+
+  int nab;
+  for(int i=0; i<nR; i++)
+  {
+    nab = (*iva)[i] - (*ivb)[i];
+    // b does not divide a
+    if(nab < 0)
+    {
+      result = NULL;
+      return result;
+    }
+    //define a polynomial which is a variable of the basering
+    ptmp = (poly) pmInit(currRing->names[i], ok);  //p:=xi
+    ppotenz = pPower(ptmp, nab);
+    result = pMult(result, ppotenz);
+  }
+  nn = nDiv(pGetCoeff(a), pGetCoeff(b));
+  result = pMult_nn(result, nn);
+  nDelete(&nn);
+
+  return result;
+}
+
+
+/***24.10.00 *****************************************
+ *      compute a product of two monoms a and b      *
+ *      i.e. leading term of two polynoms a and b    *
+ *****************************************************/
+static poly MpMult(poly a, poly b)
+{
+  if(a == NULL || b == NULL)
+    return a;
+
+  int nR = currRing->N;
+  BOOLEAN ok = TRUE;
+
+  poly  ptmp, ppotenz;
+  poly result = pISet(1);  // result := 1
+  intvec* ivab = ivAdd(MExpPol(a), MExpPol(b));
+
+  for(int i=0; i<nR; i++)
+  {
+    //define a polynomial which is a variable of the basering
+    ptmp = pmInit(currRing->names[i], ok);
+    ppotenz = pPower(ptmp, (*ivab)[i]);
+    result = pMult(result, ppotenz);
+  }
+  number nn = nMult(pGetCoeff(a), pGetCoeff(b));
+  result = pMult_nn(result, nn);
+
+  return result;
+}
+
+
+poly  MivSame(intvec* u , intvec* v)
+{
+  assume(u->length() == v->length());
+
+  int i, niv = u->length();
+
+  for (i=0; i<niv; i++)
+    if ((*u)[i] != (*v)[i])
+      return pISet(1);
+
+  return (poly) NULL;
+}
+
+poly  M3ivSame(intvec* temp, intvec* u , intvec* v)
+{
+  assume(temp->length() == u->length() && u->length() == v->length());
+
+  if(MivSame(temp, u) == NULL)
+    return (poly) NULL;
+  if(MivSame(temp, v) == NULL)
+    return pISet(1);
+  return pISet(2);
+}
+
+
+/************************
+ *  Define a monom x^iv *
+ ************************/
+poly MPolVar(intvec* iv)
+{
+  int i, niv = pVariables;
+
+  poly ptemp = pOne();
+  poly pvar, ppotenz;
+  BOOLEAN ok = TRUE;
+
+  for(i=0; i<niv; i++)
+  {
+    pvar = (poly) pmInit(currRing->names[i], ok);  //p:=x_i
+    ppotenz = pPower(pvar, (*iv)[i]);
+    ptemp = pMult(ptemp, ppotenz);
+  }
+  return ptemp;
+}
+
+
+/* compute a Groebner basis of an ideal */
+ideal Mstd(ideal G)
+{
+  G = kStd(G, NULL, testHomog, NULL);
+  G = kInterRed(G, NULL);//5.02
+  idSkipZeroes(G);
+  return G;
+}
+
+/* compute a Groebner basis of a homogenoues ideal */
+ideal Mstdhom(ideal G)
+{
+  G = kStd(G, NULL, isHomog, NULL);
+  G = kInterRed(G, NULL);//21.02
+  idSkipZeroes(G);
+  return G;
+}
+
+/* compute a reduced Groebner basis of a Groebner basis */
+ideal MkInterRed(ideal G)
+{
+  if(G == NULL)
+    return G;
+
+  G = kInterRed(G, NULL);
+  idSkipZeroes(G);
+  return G;
+}
+
+
+/*****************************************************
+ *              PERTURBATION WALK                    *
+ *****************************************************/
+
+/***************************************
+* create an ordering matrix as intvec  *
+****************************************/
+intvec* MivMatrixOrder(intvec* iv)
+{
+  int i,j;
+  int nR = currRing->N;
+  intvec* ivm = new intvec(nR*nR);
+
+  for(i=0; i<nR; i++)
+    (*ivm)[i] = (*iv)[i];
+
+  for(i=1; i<nR; i++)
+    (*ivm)[i*nR+i-1] = (int) 1;
+
+  return ivm;
+}
+
+static intvec* MivMatUnit(void)
+{
+  int nR = currRing->N;
+  intvec* ivm = new intvec(nR);
+
+  (*ivm)[0] = 1;
+
+  return ivm;
+}
+
+/* return iv = (1, ..., 1) */
+intvec* Mivdp(int nR)
+{
+  int i;
+  intvec* ivm = new intvec(nR);
+
+  for(i=0; i<nR; i++)
+    (*ivm)[i] = 1;
+
+  return ivm;
+}
+
+/* return iv = (1,0, ..., 0) */
+intvec* Mivlp(int nR)
+{
+  int i;
+  intvec* ivm = new intvec(nR);
+  (*ivm)[0] = 1;
+
+  return ivm;
+}
+
+intvec* Mivdp0(int nR)
+{
+  int i;
+  intvec* ivm = new intvec(nR);
+  (*ivm)[nR-1] = 0;
+  for(i=0; i<nR-1; i++)
+    (*ivm)[i] = 1;
+
+  return ivm;
+}
+
+/*****************************************************************************
+* If target_ord = intmat(A1, ..., An) then calculate the perturbation        *
+* vectors                                                                    *
+*   tau_p_dep = inveps^(p_deg-1)*A1 + inveps^(p_deg-2)*A2 +... + A_p_deg     *
+* where                                                                      *
+*      inveps > totaldegree(G)*(max(A2)+...+max(A_p_deg))                    *
+* intmat target_ord is an integer order matrix of the monomial ordering of   *
+* basering.                                                                  *
+* This programm computes a perturbated vector with a p_deg perturbation      *
+* degree which smaller than the numbers of varibles                          *
+******************************************************************************/
+/* ivtarget is a matrix of a degree reverse lex. order */
+intvec* MPertVectors(ideal G, intvec* ivtarget, int pdeg)
+{
+  int nV = currRing->N;
+  //assume(pdeg <= nV && pdeg >= 0);
+
+  int i, j;
+  intvec* pert_vector =  new intvec(nV);
+
+  //Checking that the perturbated degree is valid
+  if(pdeg > nV || pdeg <= 0)
+  {
+    WerrorS("The perturbed degree is wrong!!");
+    return pert_vector;
+  }
+  for(i=0; i<nV; i++)
+    (*pert_vector)[i]=(*ivtarget)[i];
+
+  if(pdeg == 1)
+    return pert_vector;
+
+  // Calculate max1 = Max(A2)+Max(A3)+...+Max(Apdeg),
+  // where the Ai are the i-te rows of the matrix target_ord.
+
+  int ntemp, maxAi, maxA=0;
+  //for(i=1; i<pdeg; i++)
+  for(i=0; i<pdeg; i++) //for "dp"
+  {
+    maxAi = (*ivtarget)[i*nV];
+    for(j=i*nV+1; j<(i+1)*nV; j++)
+    {
+      ntemp = (*ivtarget)[j];
+      if(ntemp > maxAi)
+        maxAi = ntemp;
+    }
+    maxA += maxAi;
+  }
+
+  // Calculate inveps = 1/eps, where 1/eps > totaldeg(p)*max1 for all p in G.
+  int inveps, tot_deg = 0, maxdeg;
+
+  intvec* ivUnit = Mivdp(nV);//19.02
+  for(i=0; i<IDELEMS(G); i++)
+  {
+    //maxdeg = pTotaldegree(G->m[i], currRing); //it's wrong for ex1,2,rose
+    maxdeg = MwalkWeightDegree(G->m[i], ivUnit);
+    if (maxdeg > tot_deg )
+      tot_deg = maxdeg;
+  }
+  inveps = (tot_deg * maxA) + 1;
+
+  // pert(A1) = inveps^(pdeg-1)*A1 + inveps^(pdeg-2)*A2+...+A_pdeg,
+  // pert_vector := A1
+  for ( i=1; i < pdeg; i++ )
+    for(j=0; j<nV; j++)
+       (*pert_vector)[j] = inveps*(*pert_vector)[j] + (*ivtarget)[i*nV+j];
+
+
+  int temp = (*pert_vector)[0];
+  for(i=1; i<nV; i++)
+  {
+    temp = gcd(temp, (*pert_vector)[i]);
+    if(temp == 1)
+      break;
+  }
+  if(temp != 1)
+    for(i=0; i<nV; i++)
+      (*pert_vector)[i] = (*pert_vector)[i] / temp;
+
+  //test_w_in_Cone(G, pert_vector);
+  return pert_vector;
+}
+
+/* ivtarget is a matrix of the lex. order */
+intvec* MPertVectorslp(ideal G, intvec* ivtarget, int pdeg)
+{
+  int nV = currRing->N;
+  //assume(pdeg <= nV && pdeg >= 0);
+
+  int i, j;
+  intvec* pert_vector =  new intvec(nV);
+
+  //Checking that the perturbated degree is valid
+  if(pdeg > nV || pdeg <= 0)
+  {
+    WerrorS("The perturbed degree is wrong!!");
+    return pert_vector;
+  }
+  for(i=0; i<nV; i++)
+    (*pert_vector)[i]=(*ivtarget)[i];
+
+  if(pdeg == 1)
+    return pert_vector;
+
+  // Calculate max1 = Max(A2)+Max(A3)+...+Max(Apdeg),
+  // where the Ai are the i-te rows of the matrix target_ord.
+  int ntemp, maxAi, maxA=0;
+  for(i=1; i<pdeg; i++)
+  //for(i=0; i<pdeg; i++) //for "dp"
+  {
+    maxAi = (*ivtarget)[i*nV];
+    for(j=i*nV+1; j<(i+1)*nV; j++)
+    {
+      ntemp = (*ivtarget)[j];
+      if(ntemp > maxAi)
+        maxAi = ntemp;
+    }
+    maxA += maxAi;
+  }
+
+  // Calculate inveps := 1/eps, where 1/eps > deg(p)*max1 for all p in G.
+  int inveps, tot_deg = 0, maxdeg;
+
+  intvec* ivUnit = Mivdp(nV);//19.02
+  for(i=0; i<IDELEMS(G); i++)
+  {
+    //maxdeg = pTotaldegree(G->m[i], currRing); //it's wrong for ex1,2,rose
+    maxdeg = MwalkWeightDegree(G->m[i], ivUnit);
+    if (maxdeg > tot_deg )
+      tot_deg = maxdeg;
+  }
+  inveps = (tot_deg * maxA) + 1;
+
+  // Pert(A1) = inveps^(pdeg-1)*A1 + inveps^(pdeg-2)*A2+...+A_pdeg,
+
+  for ( i=1; i < pdeg; i++ )
+    for(j=0; j<nV; j++)
+      (*pert_vector)[j] = inveps*((*pert_vector)[j]) + (*ivtarget)[i*nV+j];
+
+  int temp = (*pert_vector)[0];
+  for(i=1; i<nV; i++)
+  {
+    temp = gcd(temp, (*pert_vector)[i]);
+    if(temp == 1)
+      break;
+  }
+  if(temp != 1)
+    for(i=0; i<nV; i++)
+      (*pert_vector)[i] = (*pert_vector)[i] / temp;
+
+  //test_w_in_Cone(G, pert_vector);
+  return pert_vector;
+}
+
+
+/***************************************************************
+ *                    FRACTAL WALK                             *
+ ***************************************************************/
+
+/*****  define a lexicographic order matrix as intvec  ********/
+intvec* MivMatrixOrderlp(int nV)
+{
+  int i;
+  intvec* ivM = new intvec(nV*nV);
+
+  for(i=0; i<nV; i++)
+    (*ivM)[i*nV + i] = 1;
+
+  return(ivM);
+}
+
+intvec* MivMatrixOrderdp(int nV)
+{
+  int i;
+  intvec* ivM = new intvec(nV*nV);
+
+  for(i=0; i<nV; i++)
+    (*ivM)[i] = 1;
+
+  for(i=1; i<nV; i++)
+    (*ivM)[(i+1)*nV - i] = -1;
+
+  return(ivM);
+}
+
+//creates an intvec of the monomial order Wp(ivstart)
+intvec* MivWeightOrderlp(intvec* ivstart)
+{
+  int i;
+  int nV = ivstart->length();
+  intvec* ivM = new intvec(nV*nV);
+
+  for(i=0; i<nV; i++)
+    (*ivM)[i] = (*ivstart)[i];
+
+  for(i=1; i<nV; i++)
+    (*ivM)[i*nV + i-1] = 1;
+
+  return(ivM);
+}
+
+intvec* MivWeightOrderdp(intvec* ivstart)
+{
+  int i;
+  int nV = ivstart->length();
+  intvec* ivM = new intvec(nV*nV);
+
+  for(i=0; i<nV; i++)
+    (*ivM)[i] = (*ivstart)[i];
+
+  for(i=0; i<nV; i++)
+    (*ivM)[nV+i] = 1;
+
+  for(i=2; i<nV; i++)
+    (*ivM)[(i+1)*nV - i] = -1;
+
+  return(ivM);
+}
+
+intvec* MivUnit(int nV)
+{
+  int i;
+  intvec* ivM = new intvec(nV);
+
+  for(i=0; i<nV; i++)
+    (*ivM)[i] = 1;
+
+  return(ivM);
+}
+
+/************************************************************************
+*  compute a perturbed weight vector of a matrix order w.r.t. an ideal  *
+*************************************************************************/
+intvec* Mfpertvector(ideal G, intvec* ivtarget)
+//intvec* Mfpertvector(ideal G)
+{
+  int i, j;
+  int nV = currRing->N;
+  int niv = nV*nV;
+
+  // Calculate max1 = Max(A2) + Max(A3) + ... + Max(AnV),
+  // where the Ai are the i-te rows of the matrix 'targer_ord'.
+  int ntemp, maxAi, maxA=0;
+  for(i=1; i<nV; i++) //30.03
+    //for(i=0; i<nV; i++) //for "dp"
+  {
+    maxAi = (*ivtarget)[i*nV];
+    for(j=i*nV+1; j<(i+1)*nV; j++)
+    {
+      ntemp = (*ivtarget)[j];
+      if(ntemp > maxAi)
+        maxAi = ntemp;
+    }
+    maxA = maxA + maxAi;
+  }
+  intvec* ivUnit = Mivdp(nV);
+
+  // Calculate inveps = 1/eps, where 1/eps > deg(p)*max1 for all p in G.
+  int inveps, tot_deg = 0, maxdeg;
+  for(i=0; i<IDELEMS(G); i++)
+  {
+    maxdeg = MwalkWeightDegree(G->m[i], ivUnit);
+    //maxdeg = pTotaldegree(G->m[i]);
+    if (maxdeg > tot_deg )
+      tot_deg = maxdeg;
+  }
+  inveps = (tot_deg * maxA) + 1;
+
+  // Calculate the perturbed target orders:
+  intvec* ivtemp = new intvec(nV);
+  intvec* pert_vector = new intvec(niv);
+  for(i=0; i<nV; i++)
+  {
+    ntemp = (*ivtarget)[i];
+    (* ivtemp)[i] = ntemp;
+    (* pert_vector)[i] = ntemp;
+  }
+  for(i=1; i<nV; i++)
+  {
+    for(j=0; j<nV; j++)
+      (* ivtemp)[j] = inveps*(*ivtemp)[j] + (*ivtarget)[i*nV+j];
+    for(j=0; j<nV; j++)
+      (* pert_vector)[i*nV+j] = (* ivtemp)[j];
+  }
+  omFree((ADDRESS)ivtemp);
+  return pert_vector;
+}
+
+
+/**********************************************************************
+ *  computes a transformation matrix as an ideal L
+    an i-th element of L is a representasion of an i-th element M w.r.t.
+    the generators of Gomega
+********************************************************************/
+
+ideal MidLift(ideal Gomega, ideal M)
+{
+  //M = idLift(Gomega, M, NULL, FALSE, FALSE, TRUE, NULL);
+  //return M;
+  //17.04.01
+  ideal Mtmp = idInit(IDELEMS(M),1);
+  Mtmp = idLift(Gomega, M, NULL, FALSE, FALSE, TRUE, NULL);
+  idSkipZeroes(Mtmp);
+  M = idCopy(Mtmp);
+
+  omFree((ADDRESS)Mtmp);
+  return M;
+}
+
+/****************************************************************
+ * Multiplikation of two ideals by elementwise                  *
+ * i.e. Let be A := (a_i) and B := (b_i), return C := (a_i*b_i) *
+ ****************************************************************/
+ideal MidMultLift(ideal A, ideal B)
+{
+  int mA = IDELEMS(A), mB = IDELEMS(B);
+  ideal result;
+
+  if(A==NULL || B==NULL)
+    return result;
+
+  if(mB < mA)
+  {
+    mA = mB;
+    result = idInit(mA, 1);
+  }
+  else
+  result = idInit(mA, 1);
+
+  int i, k=0;
+  for(i=0; i<mA; i++)
+    if(A->m[i] != NULL)
+    {
+      result->m[k] = pMult(pCopy(A->m[i]), pCopy(B->m[i]));
+      k++;
+    }
+
+  //idSkipZeroes(result); //walkalp_CON
+  ideal res = idCopy(result);
+  idDelete(&result);
+  return res;
+}
+
+//computes a  multiplication of two ideals L and G, ie. L[i]*G[i]
+ideal MLiftLmalG(ideal L, ideal G)
+{
+  int i, j;
+  ideal Gtemp = idInit(IDELEMS(L),1);
+  ideal mG = idInit(IDELEMS(G),1);
+  poly pGtmp = NULL, pmG;
+  ideal T;
+
+  for(i=0; i<IDELEMS(L); i++)
+  {
+    T = idVec2Ideal(L->m[i]);
+    mG = MidMultLift(T,G);
+    idSkipZeroes(mG);
+
+    for(j=0; j<IDELEMS(mG); j++)
+    {
+      pGtmp = pAdd(pGtmp, mG->m[j]);
+    }
+    Gtemp->m[i] = pCopy(pGtmp);
+  }
+  idSkipZeroes(Gtemp);
+
+  //compute a reduced Groebner basis of GF
+  //Gtemp = kInterRed(Gtemp, NULL);
+  L = idCopy(Gtemp);
+
+  omFree((ADDRESS)mG);
+  omFree((ADDRESS)Gtemp);
+  return L;
+}
+
+/*********************************************************************
+ * G is a red. Groebner basis w.r.t. <_1                             *
+ * Gomega is an initial form ideal of <G> w.r.t. a weight vector w   *
+ * M is a subideal of <Gomega> and M selft is a red. Groebner basis  *
+ *    of the ideal <Gomega> w.r.t. <_w                               *
+ * Let m_i = h1.gw1 + ... + hs.gws for each m_i in M; gwi in Gomega  *
+ * return F with n(F) = n(M) and f_i = h1.g1 + ... + hs.gs for each i*
+ ********************************************************************/
+ /* MidLift + MLiftLmalG */
+ideal MLiftLmalGNew(ideal Gomega, ideal M, ideal G)
+{
+  int i, j;
+  M = idLift(Gomega, M, NULL, FALSE, FALSE, TRUE, NULL);
+  int nM = IDELEMS(M);
+  ideal Gtemp = idInit(IDELEMS(M),1);
+  ideal mG = idInit(IDELEMS(G),1);
+  poly pmG, pGtmp = NULL;
+  ideal T;
+
+  for(i=0; i<nM; i++)
+  {
+    T = idVec2Ideal(M->m[i]);
+    mG = MidMultLift(T, G);
+
+    for(j=0; j<IDELEMS(mG); j++)
+      pGtmp = pAdd(pGtmp, mG->m[j]);
+
+    Gtemp->m[i] = pCopy(pGtmp);
+  }
+  idSkipZeroes(Gtemp);
+
+  M = idCopy(Gtemp);
+
+  omFree((ADDRESS)mG);
+  omFree((ADDRESS)Gtemp);
+  return M;
+}
+
+/******************************************************************************
+ * compute a next weight vector on the line from curr_weight to target_weight *
+ * and it still stays in the cone of the ideal G where the curr_weight too    *
+ *****************************************************************************/
+intvec* MwalkNextWeight(intvec* curr_weight, intvec* target_weight, ideal G)
+{
+  assume(currRing != NULL && curr_weight != NULL &&
+         target_weight != NULL && G != NULL);
+
+  int nRing = currRing->N;
+  int nG = IDELEMS(G);
+  intvec* ivtemp;
+
+  long t_zaehler = 0, t_nenner = 0;
+  long s_zaehler, s_nenner, temp, MwWd;
+  long deg_w0_p1, deg_d0_p1;
+  int j;
+
+  intvec* diff_weight = ivSub(target_weight, curr_weight);
+  poly g;
+  for (j=0; j<nG; j++)
+  {
+    g = G->m[j];
+    if (g != NULL)
+    {
+      ivtemp = MExpPol(g);
+      deg_w0_p1 = MivDotProduct(ivtemp, curr_weight);
+      deg_d0_p1 = MivDotProduct(ivtemp, diff_weight);
+
+      pIter(g);
+
+      while (g != NULL)
+      {
+        //s_zaehler = deg_w0_p1 - pGetOrder(g);
+	ivtemp = MExpPol(g);
+	MwWd = MivDotProduct(ivtemp, curr_weight);
+	s_zaehler = deg_w0_p1 - MwWd;
+
+        if (s_zaehler != 0)
+        {
+          //s_nenner = MwalkWeightDegree(g, diff_weight) - deg_d0_p1;
+	  MwWd = MivDotProduct(ivtemp, diff_weight);
+          s_nenner = MwWd - deg_d0_p1;
+
+          // check for 0 < s <= 1
+          if ( (s_zaehler > 0 && s_nenner >= s_zaehler) ||
+               (s_zaehler < 0 && s_nenner <= s_zaehler) )
+          {
+            // make both positive
+            if (s_zaehler < 0)
+            {
+              s_zaehler = - s_zaehler;
+              s_nenner = - s_nenner;
+            }
+
+            // compute a simply fraction of s
+            cancel(s_zaehler, s_nenner);
+
+            if(t_nenner != 0)
+            {
+              if(s_zaehler * t_nenner < s_nenner * t_zaehler)
+              {
+                t_nenner = s_nenner;
+                t_zaehler = s_zaehler;
+              }	
+            }
+            else
+            {
+              t_nenner = s_nenner;
+              t_zaehler = s_zaehler;
+            }
+          }
+        }
+        pIter(g); //g = g - pHead(g);
+      }
+    }
+  }
+  if(t_nenner == 0)
+  {
+    diff_weight = ivCopy(curr_weight);
+    return diff_weight;
+  }
+
+  if(t_nenner == 1 && t_zaehler == 1)
+  {
+    diff_weight = ivCopy(target_weight);
+    return diff_weight;
+  }
+
+  // construct a new weight vector
+  for (j=0; j<nRing; j++)
+  {
+    (*diff_weight)[j] = t_nenner*(*curr_weight)[j] +
+      t_zaehler*(*diff_weight)[j];
+  }
+
+  // and take out the content
+  temp = (*diff_weight)[0];
+  if(temp != 1)
+    for (j=1; j<nRing; j++)
+    {
+      temp = gcd(temp, (*diff_weight)[j]);
+      if (temp == 1)
+	return diff_weight;
+    }
+
+  for (j=0; j<nRing; j++)
+      (*diff_weight)[j] = (*diff_weight)[j] / temp;
+
+  return diff_weight;
+}
+
+/* Condition: poly f must be divided by the ideal G */
+/* Let f = h1g1+...+hsgs, then the result is (h1, ... ,hs) */
+static ideal MNormalForm(poly f, ideal G)
+{
+  int nG = IDELEMS(G);
+  ideal lmG = idInit(nG, 1);
+  ideal result = idInit(nG, 1);
+  int i, ind=0, ncheck=0;
+
+  for(i=0; i<nG; i++)
+  {
+    lmG->m[i] = pHead(G->m[i]);
+    result->m[i] = NULL;
+  }
+
+  poly h = f;
+  poly lmh, q, pmax = pISet(1), quot, qtmp=NULL;
+  int ntest = 0;
+  while(h != NULL)
+  {
+    lmh = pHead(h);
+    for(i=0; i<nG; i++)
+    {
+      q = MpDiv(lmh, lmG->m[i]);
+
+      if(q != NULL)
+      {
+	  if(ncheck == 0)
+	  {
+	    result->m[i] = pCopy(pAdd(result->m[i], q));
+	    h = pSub(h, pMult(q, pCopy(G->m[i])));
+	    break;
+	  }
+	  else {
+	    h = pSub(f, pMult(q, pCopy(G->m[i])));
+	    if(quot != NULL)
+	    {
+	      ntest = 1;
+	      qtmp = q;
+	      ind = i;
+	      ncheck = 0;
+	    }
+	  }
+      }
+    }
+    if(i==nG)
+    {
+      f = h;
+      pIter(h);
+      ncheck = 1;
+    }
+
+    if(ntest == 1)
+    {
+      result->m[ind] = pCopy(pAdd(result->m[ind], qtmp));
+      ntest = 0;
+    }
+  }
+  ideal rest = idCopy(result);
+  idDelete(&result);
+  idDelete(&lmG);
+  return rest;
+}
+
+/* GW is an initial form of the ideal G w.r.t. a weight vector */
+/* polynom f is divided by the ideal GW                        */
+/* Let f := h_1.gw_1 + ... + h_s.gw_s, then the result is      */
+/*          h_1.g_1 + ... + h_s.g_s                            */
+static poly MpolyConversion(poly f, ideal GW, ideal G)
+{
+  ideal H = MNormalForm(f, GW);
+  ideal HG = MidMultLift(H, G);
+
+  poly result = NULL;
+  int i;
+  int nG = IDELEMS(G);
+
+  for(i=0; i<nG; i++)
+   result = pCopy(pAdd(result, HG->m[i]));
+
+  return result;
+}
+
+/* GW is an initial form of the ideal G w.r.t. a weight vector */
+/* Each polynom f of the ideal M is divided by the ideal GW    */
+/* Let m_i := h_1.gw_1 + ... + h_s.gw_s, then the i-th polynom */
+/* of result is  f_i := h_1.g_1 + ... + h_s.g_s                */
+ideal MidealConversion(ideal M, ideal GW, ideal G)
+{
+  int nM = IDELEMS(M);
+  int i;
+
+  for(i=0; i<nM; i++)
+  {
+    M->m[i] = MpolyConversion(M->m[i], GW, G);
+  }
+  ideal result = idCopy(M);
+  return result;
+}
+
+/* check that the monomial f is reduced by a monomial ideal G */
+static inline int MCheckpRedId(poly f, ideal G)
+{
+  int nG = IDELEMS(G);
+  int i;
+  poly q;
+
+  for(i=0; i<nG; i++)
+  {
+    q = MpDiv(f, G->m[i]);
+    if(q != NULL)
+      return 0;
+  }
+  return 1;
+}
+
+poly MpReduceId(poly f, ideal GO)
+{
+  ideal G = idCopy(GO);
+  int nG = IDELEMS(G);
+  int i, pcheck;
+  ideal HG = idInit(nG, 1);
+
+  for(i=0; i<nG; i++)
+    HG->m[i] = pHead(G->m[i]);
+
+  poly h = f;
+  poly lmh, q,qg, result = NULL;
+
+  while(h!=NULL)
+  {
+    f = pCopy( h);
+    lmh = pHead(h);
+
+    if(MCheckpRedId(lmh, HG) != 0)
+    {
+      result = pCopy(pAdd(result, lmh));
+      pIter(h);
+    }
+    else
+      for(i=0; i<nG; i++)
+      {
+	q = MpDiv(lmh, HG->m[i]);
+	if(q != NULL)
+	{
+	  f = pAdd(result, f);
+	  qg = pMult(q, G->m[i]);
+	  h = pSub(f, qg);
+	  result = NULL;
+
+	  lmh = pHead(h);
+	  pcheck = MCheckpRedId(lmh, HG);
+	  if(pcheck != 0)
+	  {
+	    break;
+	  }
+	}
+      }
+ }
+ idDelete(&HG);
+ return result;
+}
+
+/* return f, if a head term of f is not divided by a head ideal M */
+static poly MpMinimId(poly f, ideal M)
+{
+  int nM = IDELEMS(M);
+  ideal HM = idInit(nM, 1);
+  int i, pcheck;
+
+  for(i=0; i<nM; i++)
+    HM->m[i] = pCopy(M->m[i]);
+
+  poly result = pCopy(f);
+  poly hf=pHead(f), q, qtmp, h=f;
+
+  if(MCheckpRedId(pHead(f), HM) != 0)
+    goto FINISH;
+
+  while(1)
+  {
+    for(i=0; i<nM; i++)
+    {
+      q = MpDiv(hf, HM->m[i]);
+      if(q != NULL)
+	{
+	  qtmp = pMult(q, M->m[i]);
+	  h = pSub(h, qtmp);
+
+	  hf = pHead(h);
+	  pcheck = MCheckpRedId(hf, HM);
+	  if(pcheck != 0)
+	  {
+	    result = pCopy(h);
+	    goto FINISH;	
+	  }
+	  break;
+	}
+    }
+ }
+
+ FINISH:
+ idDelete(&HM);
+ return result;
+}
+
+/* return a minimal ideal of an ideal M */
+ideal MidMinimId(ideal M)
+{
+  int i,j=0;
+  ideal result = idInit(IDELEMS(M),1);
+  poly pmin;
+  for(i=0; i<IDELEMS(M); i++)
+  {
+    ideal Mtmp = idCopy(M);
+    Mtmp->m[j] = NULL;
+    idSkipZeroes(Mtmp);
+    pmin = MpMinimId(pCopy(M->m[i]), Mtmp);
+    M->m[i] = pCopy(pmin);
+    result->m[j] = pmin;
+    if(pmin == NULL)
+    {
+      i--;
+      j--;
+      idSkipZeroes(M);
+    }
+    j++;
+    idDelete(&Mtmp);
+  }
+  idSkipZeroes(result);
+  ideal res = idCopy(result);
+  idDelete(&result);
+  return res;
+}
+
+
+ideal MidMinBase(ideal G)
+{
+  if(G == NULL)
+    return G;
+
+    intvec * wth;
+    lists re = min_std(G,currQuotient,(tHomog)TRUE,&wth,NULL,0,3);
+    G = (ideal)re->m[1].data;
+    re->m[1].data = NULL;
+    re->m[1].rtyp = NONE;
+    re->Clean();
+
+  return G;
+}
+
+
+/* compute a Groebner basis of a homogenoues ideal */
+ideal MNWstdhomRed(ideal G, intvec* iv)
+{
+
+  ideal Gomega = MwalkInitialForm(G, iv);
+  G = kStd(Gomega, NULL, isHomog, NULL);
+  Gomega = MkInterRed(G);
+
+  return Gomega;
+}
+
+/*****************************************************************************
+* If target_ord = intmat(A1,..., An) then calculate the perturbation vectors *
+*     tau_p_dep = inveps^(p_deg-1)*A1 + inveps^(p_deg-2)*A2 +... + A_p_deg   *
+* where                                                                      *
+*     inveps > totaldegree(G)*(max(A2)+...+max(A_p_deg))                     *
+* and                                                                        *
+*     p_deg <= the number of variables of a basering                         *
+******************************************************************************/
+intvec* Mfivpert(ideal G, intvec* target, int p_deg)
+{
+  int i, j;
+  int nV = currRing->N;
+
+  //Checking that the perturbation degree is valid
+  if(p_deg > nV || p_deg <= 0)
+  {
+    WerrorS("The perturbed degree is wrong!!");
+    return NULL;
+  }
+
+  // Calculate max_el_rows = Max(A2)+Max(A3)+...+Max(Ap_deg),
+  //    where the Ai are the rows of the target-order matrix.
+  int nmax = 0, maxAi, ntemp;
+
+  for(i=1; i < p_deg; i++)
+  {
+    maxAi = (*target)[i*nV];
+    for(j=1; j < nV; j++)
+    {
+      ntemp = (*target)[i*nV + j];
+      if(ntemp > maxAi)
+        maxAi = ntemp;
+    }
+    nmax += maxAi;
+  }
+
+  // Calculate inv_eps := 1/eps, where 1/eps > deg(p)*max_el_rows
+  //        for all p in G.
+  int inv_eps, degG, max_deg=0;
+  intvec* ivUnit = Mivdp(nV);
+
+  for (i=0; i<IDELEMS(G); i++)
+  {
+    degG = MwalkWeightDegree(G->m[i], ivUnit);
+    if(degG > max_deg)
+      max_deg = degG;
+  }
+  inv_eps = (max_deg * nmax) + 1;
+
+
+  // Calculate the perturbed target order:
+  // Since a weight vector in Singular has to be in integral, we compute
+  // tau_p_deg = inv_eps^(p_deg-1)*A1 - inv_eps^(p_deg-2)*A2+...+A_p_deg,
+
+  intvec* ivtemp = new intvec(nV);
+  intvec* pert_vector = new intvec(nV);
+
+  for(i=0; i<nV; i++)
+  {
+    ntemp = (*target)[i];
+    (* ivtemp)[i] = ntemp;
+    (* pert_vector)[i] = ntemp;
+  }
+
+  for(i=1; i<p_deg; i++)
+  {
+    for(j=0; j<nV; j++)
+      (* ivtemp)[j] = inv_eps*(*ivtemp)[j] + (*target)[i*nV+j];
+
+    pert_vector = ivtemp;
+  }
+  omFree((ADDRESS) ivtemp);
+  return pert_vector;
+}
+
+ideal MpHeadIdeal(ideal G)
+{
+  int i, nG = IDELEMS(G);
+  ideal result = idInit(nG,1);
+
+  for(i=0; i<nG; i++)
+  {
+    result->m[i] = pHead(G->m[i]);
+  }
+
+  ideal res = idCopy(result);
+  idDelete(&result);
+  return res;
+}
+
+void* checkideal(ideal G)
+{
+  int i;
+  printf("//** Size(G)= %d, and ", IDELEMS(G));
+
+  for(i=0; i<IDELEMS(G); i++)
+  {
+    printf("G[%d] = %d, ", i, pLength(G->m[i]));
+  }
+  printf("\n");
+}
+
Index: kernel/walk.h
===================================================================
--- kernel/walk.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/walk.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,186 @@
+/*****************************************
+*  Computer Algebra System SINGULAR      *
+*****************************************/
+/* $Id: walk.h,v 1.1.1.1 2003-10-06 12:16:04 Singular Exp $ */
+/*
+* ABSTRACT: Declaration of the Groebner walk
+*/
+
+#ifndef WALK_H
+#define WALK_H
+
+#include "structs.h"
+
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT:
+// The following routines assume that pGetOrder(p) yields the scalar
+// product of the first row of the order matrix with the exponent
+// vector of p
+// Remark: This is true for all degree orderings (like dp) and block
+// orderings (like a(...),lp) BUT NOT FOR lp!!!
+//
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+
+
+
+//////////////////////////////////////////////////////////////////////
+//
+// walkNextWeight
+// Returns : weight vector for next step in Groebner walk, if exists
+//           (int) 1, if next weight vector is target_weight
+//           (int) 0, if no next weight vectro exist
+
+
+// assumes that curr_weight is first row of order matrix
+//intvec* walkNextWeight(intvec* curr_weight, intvec* target_weight, ideal G);
+
+//intvec* MwalkNextWeight(intvec* curr_weight, intvec* target_weight, ideal G);
+// assume curr_weight and target_weight are arrays of length
+// currRing->N storing current and target weight
+
+//////////////////////////////////////////////////////////////////////
+//
+// walkInitials
+// assume polys of G are ordererd decreasingly w.r.t. curr_weight
+// returns ideal consisting of leading (w.r.t. curr_weight) monomials
+//ideal walkInitials(ideal G);
+
+//intvec* walkAddIntVec(intvec* v1, intvec* v2);
+
+//int MwalkWeightDegree(poly p, intvec* weight_vector);
+
+//poly MpolyInitialForm(poly g, intvec* curr_weight);
+
+ideal  MwalkInitialForm(ideal G, intvec* curr_weight);
+
+//poly MOrderedPoly(poly p, intvec* curr_weight);
+
+//compute the next weight vector
+intvec* MwalkNextWeight(intvec* curr_weight,intvec* target_weight, ideal G);
+//intvec* MwalkNextWeightZ(intvec* curr_weight);
+//return lead exponent of the polynomial f
+//intvec* MExpPol(poly f);//11.02
+
+//return the product  of two intvecs
+//intvec* MivMult(intvec* a, intvec* b); //11.02
+intvec* Mivdp(int n);
+intvec* Mivlp(int n);
+intvec* Mivdp0(int n);
+//intvec* MivUnit(int n);
+poly MivSame(intvec* u , intvec* v);
+poly M3ivSame(intvec* next_weight, intvec* u , intvec* v);
+/***********************
+ *  create a new ring  *
+ ***********************/
+//5.12 ring MNextRing(intvec* new_weight_vector);
+
+//ring MNextRing(ring startRing, intvec* new_weight_vector);
+char* MNextRingStringC(ring startRing, intvec* new_weight_vector);
+
+// compute an intermediate Groebner basis
+//ideal MwalkStep(ideal G,intvec* origin_weight, intvec* curr_weight, intvec* weight_order);
+
+//ideal MwalkStep(ideal G, intvec* curr_weight, ring NRing);
+
+// compute a Groebner basis of an ideal G w.r.t. lexicographic order
+//ideal Mwalk(ideal G, intvec* curr_weight, intvec* target_weight);
+
+//compute the division of two monoms
+//poly MpDiv(poly a, poly b);
+
+//compute the multiplication of two monoms
+//poly MpMult(poly a, poly b);
+
+//compare a intvec to intvec NULL
+//int Mivcomp(intvec* op);
+
+//define a monomial which exponent is intvec iv
+poly MPolVar(intvec* iv);
+
+
+//int* MExpSub(int* i1, int*i2);
+
+//int* Mleadexp(poly f);
+
+//compute the multiplikation of two ideals by "elementweise"
+ideal MidMultLift(ideal A, ideal B);
+
+//poly maIMap(ring r, poly h);
+
+//compute a Groebner basis of an ideal G
+ideal Mstd(ideal G);
+ideal Mstdhom(ideal G);
+//compute a reduced Groebner basis of a Groebner basis G
+ideal MkInterRed(ideal G);
+ideal MidMinBase(ideal G);
+/********** Perturbation Walk ******************/
+/*****************************************************************************
+* compute an ordering matrix of the basering ordering.                       *
+* if the basering ordering is a block order, then its weight vector must be  *
+*    entered as the input this programm, otherwise the input is arbitrary    *
+*    integer weight vector which its size is the numbers of variables.       *
+******************************************************************************/
+
+intvec* MivMatrixOrder(intvec* iv);
+intvec* MivMatrixOrderdp(int iv);
+intvec* MPertVectors(ideal G, intvec* ivtarget, int pdeg);
+intvec* MPertVectorslp(ideal G, intvec* ivtarget, int pdeg);
+//ideal pwalk(ideal G, intvec* delta, intvec* teta, int op_deg, int tp_deg);
+
+/**** Fractal Walk *****/
+intvec* MivMatrixOrderlp(int nV);
+
+intvec* Mfpertvector(ideal G, intvec* iv);
+intvec* MivUnit(int nV);
+/*
+//ideal MFractalWalkR(ideal G, int nlev, intvec* sigma, intvec* tau, int step);
+ideal MFractalWalkR(ideal G, int nlev, intvec* tau, int step);
+ideal MFractalWalk(ideal I, intvec* ivstart);
+poly Mpsimple(poly p);
+poly Mpofid(ideal H);
+
+intvec* MivMatrixOrderlp(int n);
+*/
+intvec* MivWeightOrderlp(intvec* ivstart);
+intvec* MivWeightOrderdp(intvec* ivstart);
+//ideal Mimap(ring oldRing, ideal G);
+
+ideal MidLift(ideal Gomega, ideal M);
+ideal MLiftLmalG(ideal L, ideal G);
+ideal MLiftLmalGNew(ideal Gomega, ideal M, ideal G);
+ideal MLiftLmalGMin(ideal L, ideal G);
+//intvec* MwalkNextWeight(intvec* curr_weight,intvec* target_weight, ideal G);
+intvec* Mfivpert(ideal G, intvec* target, int p_deg);
+
+
+//int MpSame(poly a, poly b);
+//char* MidString(ideal G);
+
+
+//intvec* MwalkNextWeightZ(intvec* iv);
+//intvec* MNextWeightList(intvec* curr_weight, intvec* target_weight, ideal G);
+
+ideal MNWstdhomRed(ideal G, intvec* iv);
+poly MMinPoly(poly p, ideal G);
+ideal MMinIdeal(ideal G);
+ideal MadeLift4(ideal M, ideal pHGw, ideal Gw, ideal G);
+ideal MadeLift(ideal M, ideal Gw, ideal G);
+//poly MadepDivId(poly f, ideal Gw, ideal G);
+ideal MpHeadIdeal(ideal G);
+void* test_w_in_Cone(ideal G, intvec* iv);
+void* checkideal(ideal G);
+matrix MaMidLift(ideal Gomega, ideal M);
+
+//ideal MNormalForm(poly f, ideal G);
+//poly MpolyConversion(poly f, ideal GW, ideal G);
+ideal MidealConversion(ideal M, ideal GW, ideal G);
+//poly MCheckpRedId(poly f, ideal G);
+poly MpReduceId(poly f, ideal G);
+//poly MpMinimId(poly f, ideal M);
+ideal MidMinimId(ideal M);
+
+
+#endif  //WALK_H
Index: kernel/weight.cc
===================================================================
--- kernel/weight.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/weight.cc	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,271 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: weight.cc,v 1.1.1.1 2003-10-06 12:15:56 Singular Exp $ */
+
+/*
+* ABSTRACT:
+*/
+
+#include <math.h>
+#include "mod2.h"
+#include "structs.h"
+#include "omalloc.h"
+#include "polys.h"
+#include "intvec.h"
+#include "febase.h"
+#include "ideals.h"
+#include "weight.h"
+
+/*0 implementation*/
+#ifndef __MWERKS__
+extern "C" double (*wFunctional)(int *degw, int *lpol, int npol,
+       double *rel, double wx);
+extern "C" double wFunctionalMora(int *degw, int *lpol, int npol,
+       double *rel, double wx);
+extern "C" double wFunctionalBuch(int *degw, int *lpol, int npol,
+       double *rel, double wx);
+extern "C" void wAdd(int *A, int mons, int kn, int xx);
+extern "C" void wNorm(int *degw, int *lpol, int npol, double *rel);
+extern "C" void wFirstSearch(int *A, int *x, int mons,
+        int *lpol, int npol, double *rel, double *fopt);
+extern "C" void wSecondSearch(int *A, int *x, int *lpol,
+        int npol, int mons, double *rel, double *fk);
+extern "C" void wGcd(int *x, int n);
+extern double wNsqr;
+#else
+#include "weight0.c"
+#endif /* __MWERKS__ */
+
+static void wDimensions(polyset s, int sl, int *lpol, int *npol, int *mons)
+{
+  int  i, i1, j, k;
+  poly p, q;
+
+  i1 = j = 0;
+  for (i = 0; i <= sl; i++)
+  {
+    p = s[i];
+    if (p!=NULL)
+    {
+      k = 1;
+      q = pNext(p);
+      while (q!=NULL)
+      {
+        k++;
+        q = pNext(q);
+      }
+      if (k > 1)
+      {
+        lpol[i1++] = k;
+        j += k;
+      }
+    }
+  }
+  *npol = i1;
+  *mons = j;
+}
+
+
+static void wInit(polyset s, int sl, int mons, int *A)
+{
+  int  n, a, i, j, *B, *C;
+  poly p, q;
+  int *pl;
+
+  B = A;
+  n = pVariables;
+  a = (n + 1) * sizeof(int);
+  pl = (int *)omAlloc(a);
+  for (i = 0; i <= sl; i++)
+  {
+    p = s[i];
+    if (p!=NULL)
+    {
+      q = pNext(p);
+      if (q!=NULL)
+      {
+        C = B;
+        B++;
+        pGetExpV(p, pl);
+        for (j = 0; j < n; j++)
+        {
+          *C = pl[j+1];
+          C += mons;
+        }
+      }
+      while (q!=NULL)
+      {
+        C = B;
+        B++;
+        pGetExpV(q, pl);
+        for (j = 0; j < n; j++)
+        {
+          *C = pl[j+1];
+          C += mons;
+        }
+        pIter(q);
+      }
+    }
+  }
+  omFreeSize((ADDRESS)pl, a);
+}
+
+void wCall(polyset s, int sl, int *x)
+{
+  int  n, q, npol, mons, i;
+  int  *A, *xopt, *lpol, *degw;
+  double  f1, fx, eps, *rel;
+  void *adr;
+
+  n = pVariables;
+  lpol = (int * )omAlloc((sl + 1) * sizeof(int));
+  wDimensions(s, sl, lpol, &npol, &mons);
+  xopt = x + (n + 1);
+  for (i = n; i!=0; i--)
+    xopt[i] = 1;
+  if (mons==0)
+  {
+    omFreeSize((ADDRESS)lpol, (sl + 1) * sizeof(int));
+    return;
+  }
+  adr = (void * )omAllocAligned(npol * sizeof(double));
+  rel = (double*)adr;
+  q = (n + 1) * mons * sizeof(int);
+  A = (int * )omAlloc(q);
+  wInit(s, sl, mons, A);
+  degw = A + (n * mons);
+  memset(degw, 0, mons * sizeof(int));
+  for (i = n; i!=0; i--)
+    wAdd(A, mons, i, 1);
+  wNorm(degw, lpol, npol, rel);
+  f1 = (*wFunctional)(degw, lpol, npol, rel, (double)1.0);
+  if (TEST_OPT_PROT) Print("// %e\n",f1);
+  eps = f1;
+  fx = (double)2.0 * eps;
+  memset(x, 0, (n + 1) * sizeof(int));
+  wFirstSearch(A, x, mons, lpol, npol, rel, &fx);
+  if (TEST_OPT_PROT) Print("// %e\n",fx);
+  memcpy(x + 1, xopt + 1, n * sizeof(int));
+  memset(degw, 0, mons * sizeof(int));
+  for (i = n; i!=0; i--)
+  {
+    x[i] *= 16;
+    wAdd(A, mons, i, x[i]);
+  }
+  wSecondSearch(A, x, lpol, npol, mons, rel, &fx);
+  if (TEST_OPT_PROT) Print("// %e\n",fx);
+  if (fx >= eps)
+  {
+    for (i = n; i!=0; i--)
+      xopt[i] = 1;
+  }
+  else
+  {
+    wGcd(xopt, n);
+//    if (BTEST1(22))
+//    {
+//      f1 = fx + (double)0.1 * (f1 - fx);
+//      wSimple(x, n);
+//      memset(degw, 0, mons * sizeof(int));
+//      for (i = n; i!=0; i--)
+//        wAdd(A, mons, i, x[i]);
+//      eps = wPrWeight(x, n);
+//      fx = (*wFunctional)(degw, lpol, npol, rel, eps);
+//      if (fx < f1)
+//      {
+//        if (TEST_OPT_PROT) Print("// %e\n",fx);
+//        memcpy(xopt + 1, x + 1, n * sizeof(int));
+//      }
+//    }
+  }
+  omFreeSize((ADDRESS)A, q);
+  omFreeSize((ADDRESS)lpol, (sl + 1) * sizeof(int));
+  omFreeSize((ADDRESS)adr, npol * sizeof(double));
+}
+
+
+void kEcartWeights(polyset s, int sl, short *eweight)
+{
+  int  n, i;
+  int  *x;
+
+  *eweight = 0;
+  n = pVariables;
+  wNsqr = (double)2.0 / (double)n;
+  if (pOrdSgn == -1)
+    wFunctional = wFunctionalMora;
+  else
+    wFunctional = wFunctionalBuch;
+  x = (int * )omAlloc(2 * (n + 1) * sizeof(int));
+  wCall(s, sl, x);
+  for (i = n; i!=0; i--)
+    eweight[i] = x[i + n + 1];
+  omFreeSize((ADDRESS)x, 2 * (n + 1) * sizeof(int));
+}
+
+short * iv2array(intvec * iv)
+{
+  short *s=(short *)omAlloc0((pVariables+1)*sizeof(short));
+  int len=0;
+  if(iv!=NULL)
+    len=iv->length();
+  int i;
+  //for(i=pVariables;i>len;i--) s[i]=1;
+  for(i=len;i>0;i--)               s[i]=(*iv)[i-1];
+  return s;
+}
+
+/*2
+*computes the degree of the leading term of the polynomial
+*with respect to given ecartWeights
+*used for Graebes method if BTEST1(31) is set
+*/
+long totaldegreeWecart(poly p, ring r)
+{
+  int i;
+  long j =0;
+
+  for (i=r->N; i; i--)
+    j += (int)(p_GetExp(p,i,r) * ecartWeights[i]);
+  return  j;
+}
+
+/*2
+*computes the degree of the leading term of the polynomial
+*with respect to given weights
+*/
+long totaldegreeWecart_IV(poly p, ring r, const short *w)
+{
+  int i;
+  long j =0;
+
+  for (i=r->N; i; i--)
+    j += (int)(p_GetExp(p,i,r) * w[i]);
+  return  j;
+}
+
+/*2
+*computes the maximal degree of all terms of the polynomial
+*with respect to given ecartWeights and
+*computes the length of the polynomial
+*used for Graebes method if BTEST1(31) is set
+*/
+long maxdegreeWecart(poly p,int *l, ring r)
+{
+  short k=p_GetComp(p, r);
+  int ll=1;
+  long t,max;
+
+  max=totaldegreeWecart(p, r);
+  pIter(p);
+  while ((p!=NULL) && (p_GetComp(p, r)==k))
+  {
+    t=totaldegreeWecart(p, r);
+    if (t>max) max=t;
+    ll++;
+    pIter(p);
+  }
+  *l=ll;
+  return max;
+}
Index: kernel/weight.h
===================================================================
--- kernel/weight.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/weight.h	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,35 @@
+#ifndef WEIGHT_H
+#define WEIGHT_H
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/*
+* ABSTRACT
+*/
+/* $Id: weight.h,v 1.1.1.1 2003-10-06 12:15:57 Singular Exp $ */
+
+#include "structs.h"
+
+extern short * ecartWeights;
+extern pFDegProc pFDegOld;
+extern pLDegProc pLDegOld;
+
+void kEcartWeights(polyset s, int sl, short *eweight);
+BOOLEAN kWeight(leftv res,leftv id);
+BOOLEAN kQHWeight(leftv res,leftv v);
+long maxdegreeWecart(poly p,int *l, ring r = currRing);
+long totaldegreeWecart(poly p, ring r = currRing);
+long totaldegreeWecart_IV(poly p, ring r, const short *w);
+
+short * iv2array(intvec * iv);
+
+// internal:
+extern double wNsqr;
+extern "C" double (*wFunctional)(int *degw, int *lpol, int npol,
+       double *rel, double wx);
+extern "C" double wFunctionalBuch(int *degw, int *lpol, int npol,
+       double *rel, double wx);
+void wCall(polyset s, int sl, int *x);
+
+#endif
+
Index: kernel/weight0.c
===================================================================
--- kernel/weight0.c	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
+++ kernel/weight0.c	(revision 35aab3657393a3d870690b1cf2533f274e1c31f0)
@@ -0,0 +1,486 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id: weight0.c,v 1.1.1.1 2003-10-06 12:16:05 Singular Exp $ */
+
+/*
+* ABSTRACT:
+*/
+
+#include <math.h>
+#include <string.h>
+#include "mod2.h"
+#include "omalloc.h"
+#include "structs.h"
+
+double wFunctionalMora(int *degw, int *lpol, int npol,
+       double *rel, double wx);
+double wFunctionalBuch(int *degw, int *lpol, int npol,
+       double *rel, double wx);
+void wAdd(int *A, int mons, int kn, int xx);
+void wNorm(int *degw, int *lpol, int npol, double *rel);
+void wFirstSearch(int *A, int *x, int mons,
+        int *lpol, int npol, double *rel, double *fopt);
+void wSecondSearch(int *A, int *x, int *lpol,
+        int npol, int mons, double *rel, double *fk);
+void wGcd(int *x, int n);
+/*0 implementation*/
+
+short * ecartWeights=NULL;
+extern int pVariables;
+
+double wNsqr;
+double (*wFunctional)(int *degw, int *lpol, int npol,
+       double *rel, double wx);
+
+
+double wFunctionalMora(int *degw, int *lpol, int npol,
+       double *rel, double wx)
+{
+  int  i, j, e1, ecu, ecl, ec;
+  int  *ex;
+  double gfmax, gecart, ghom, pfmax;
+  double *r;
+
+  ex = degw;
+  r = rel;
+  gfmax = (double)0.0;
+  gecart = (double)0.4 + (double)npol;
+  ghom = (double)1.0;
+  for (i = 0; i < npol; i++)
+  {
+    ecl = ecu = e1 = *ex++;
+    for (j = lpol[i] - 1; j!=0; j--)
+    {
+      ec = *ex++;
+      if (ec > ecu)
+        ecu = ec;
+      else if (ec < ecl)
+        ecl = ec;
+    }
+    pfmax = (double)ecl / (double)ecu;
+    if (pfmax < ghom)
+      ghom = pfmax;
+    pfmax = (double)e1 / (double)ecu;
+    if (pfmax > (double)0.5)
+      gecart -= (pfmax * pfmax);
+    else
+      gecart -= (double)0.25;
+    ecu = 2 * ecu - ecl;
+    gfmax += (double)(ecu * ecu) * (*r++);
+  }
+  if (ghom > (double)0.8)
+  {
+    ghom *= (double)5.0;
+    gecart *= ((double)5.0 - ghom);
+  }
+  return (gfmax * gecart) / pow(wx, wNsqr);
+}
+
+
+double wFunctionalBuch(int *degw, int *lpol, int npol,
+       double *rel, double wx)
+{
+  int  i, j, ecl, ecu, ec;
+  int  *ex;
+  double gfmax, ghom, pfmax;
+  double *r;
+
+  ex = degw;
+  r = rel;
+  gfmax = (double)0.0;
+  ghom = (double)1.0;
+  for (i = 0; i < npol; i++)
+  {
+    ecu = ecl = *ex++;
+    for (j = lpol[i] - 1; j!=0 ; j--)
+    {
+      ec = *ex++;
+      if (ec < ecl)
+        ecl = ec;
+      else if (ec > ecu)
+        ecu = ec;
+    }
+    pfmax = (double)ecl / (double)ecu;
+    if (pfmax < ghom)
+      ghom = pfmax;
+    gfmax += (double)(ecu * ecu) * (*r++);
+  }
+  if (ghom > (double)0.5)
+    gfmax *= ((double)1.0 - (ghom * ghom)) / (double)0.75;
+  return gfmax / pow(wx, wNsqr);
+}
+
+
+static void wSub(int *A, int mons, int kn, int xx)
+{
+  int  i, *B, *ex;
+
+  B = A + ((kn - 1) * mons);
+  ex = A + (pVariables * mons);
+  i = mons;
+  if (xx == 1)
+  {
+    for (/* i=mons */; i!=0 ; i--)
+      *ex++ -= *B++;
+  }
+  else
+  {
+    for (/* i=mons */; i!=0 ; i--)
+      *ex++ -= (*B++) * xx;
+  }
+}
+
+
+void wAdd(int *A, int mons, int kn, int xx)
+{
+  int  i, *B, *ex;
+
+  B = A + ((kn - 1) * mons);
+  ex = A + (pVariables * mons);
+  i = mons;
+  if (xx == 1)
+  {
+    for (/* i=mons */; i!=0 ; i--)
+      *ex++ += *B++;
+  }
+  else
+  {
+    for (/* i=mons */; i!=0 ; i--)
+      *ex++ += (*B++) * xx;
+  }
+}
+
+
+void wFirstSearch(int *A, int *x, int mons,
+  int *lpol, int npol, double *rel, double *fopt)
+{
+  int  a0, a, n, xn, t, xx, y1;
+  int  *y, *degw, *xopt;
+  double  fy, fmax, wx;
+  double *pr;
+  void *adr;
+
+  fy = *fopt;
+  n = pVariables;
+  xn = n + 6 + (21 / n);
+  a0 = n * sizeof(double);
+  a = n * sizeof(int);
+  y = (int * )omAlloc(a);
+  adr = (void * )omAllocAligned(a0);
+  pr = adr;
+  *pr = (double)1.0;
+  *y = 0;
+  degw = A + (n * mons);
+  xopt = x + (n + 2);
+  t = 1;
+  loop
+  {
+    while (t < n)
+    {
+      xx = x[t] + 1;
+      wx = pr[t-1] * (double)xx;
+      y1 = y[t-1] + xx;
+      if ((y1 + n - t) <= xn)
+      {
+        pr[t] = wx;
+        y[t] = y1;
+        x[t] = xx;
+        if (xx > 1)
+          wAdd(A, mons, t, 1);
+        t++;
+      }
+      else
+      {
+        xx = x[t] - 1;
+        x[t] = 0;
+        if (xx!=0)
+          wSub(A, mons, t, xx);
+        t--;
+        if (t==0)
+        {
+          *fopt = fy;
+          omFreeSize((ADDRESS)y, a);
+          omFreeSize((ADDRESS)adr, a0);
+          return;
+        }
+      }
+    }
+    xx = xn - y[t-1];
+    wx = pr[t-1] * (double)xx;
+    x[t] = xx;
+    xx--;
+    if (xx!=0)
+      wAdd(A, mons, t, xx);
+    fmax = (*wFunctional)(degw, lpol, npol, rel, wx);
+    if (xx!=0)
+      wSub(A, mons, t, xx);
+    if (fmax < fy)
+    {
+      fy = fmax;
+      memcpy4(xopt, x + 1, a);
+    }
+    t--;
+  } /* end loop */
+}
+
+
+static double wPrWeight(int *x, int n)
+{
+  int i;
+  double y;
+
+  y = (double)x[n];
+  for (i = n - 1; i!=0 ; i--)
+    y *= (double)x[i];
+  return y;
+}
+
+
+static void wEstimate(int *A, int *x, int *lpol, int npol, int mons,
+double wx, double *rel, double *fopt, int *s0, int *s1, int *s2)
+{
+  int  n, i1, i2, k0 = 0, k1 = 0, k2 = 0;
+  int  *degw;
+  double fo1, fo2, fmax, wx1, wx2;
+
+  n = pVariables;
+  degw = A + (n * mons);
+  fo2 = fo1 = (double)1.0e10;
+  for (i1 = n; i1!=0 ; i1--)
+  {
+    if (x[i1] > 1)
+    {
+      wSub(A, mons, i1, 1);
+      wx1 = wx - wx / (double)x[i1];
+      x[i1]--;
+      fmax = (*wFunctional)(degw, lpol, npol, rel, wx1);
+      if (fmax < fo1)
+      {
+        fo1 = fmax;
+        k0 = i1;
+      }
+      for (i2 = i1; i2!=0 ; i2--)
+      {
+        if (x[i2] > 1)
+        {
+          wSub(A, mons, i2, 1);
+          wx2 = wx1 - wx1 / (double)x[i2];
+          fmax = (*wFunctional)(degw, lpol, npol, rel, wx2);
+          if (fmax < fo2)
+          {
+            fo2 = fmax;
+            k1 = i1;
+            k2 = i2;
+          }
+          wAdd(A, mons, i2, 1);
+        }
+      }
+      wAdd(A, mons, i1, 1);
+      x[i1]++;
+    }
+  }
+  if (fo1 < fo2)
+  {
+    *fopt = fo1;
+    *s0 = k0;
+  }
+  else
+  {
+    *fopt = fo2;
+    *s0 = 0;
+  }
+  *s1 = k1;
+  *s2 = k2;
+}
+
+
+void wSecondSearch(int *A, int *x, int *lpol,
+int npol, int mons, double *rel, double *fk)
+{
+  int  n, s0, s1, s2, *xopt;
+  double  one, fx, fopt, wx;
+
+  n = pVariables;
+  xopt = x + (n + 2);
+  fopt = *fk * (double)0.999999999999;
+  wx = wPrWeight(x, n);
+  one = (double)1.0;
+  loop
+  {
+    wEstimate(A, x, lpol, npol, mons, wx, rel, &fx, &s0, &s1, &s2);
+    if (fx > fopt)
+    {
+      if (s0!=0)
+        x[s0]--;
+      else if (s1!=0)
+      {
+        x[s1]--;
+        x[s2]--;
+      }
+      else
+        break;
+    }
+    else
+    {
+      fopt = fx;
+      if (s0!=0)
+      {
+        x[s0]--;
+        memcpy4(xopt, x + 1, n * sizeof(int));
+        if (s1==0)
+          break;
+      }
+      else if (s1!=0)
+      {
+        x[s1]--;
+        x[s2]--;
+        memcpy4(xopt, x + 1, n * sizeof(int));
+      }
+      else
+        break;
+    }
+    if (s0!=0)
+      wSub(A, mons, s0, 1);
+    else
+    {
+      wSub(A, mons, s1, 1);
+      wSub(A, mons, s2, 1);
+    }
+    wx = wPrWeight(x, n);
+  }
+  *fk = fopt;
+}
+
+
+void wGcd(int *x, int n)
+{
+  int i, b, a, h;
+
+  i = n;
+  b = x[i];
+  loop
+  {
+    i--;
+    if (i==0)
+      break;
+    a = x[i];
+    if (a < b)
+    {
+      h = a;
+      a = b;
+      b = h;
+    }
+    do
+    {
+      h = a % b;
+      a = b;
+      b = h;
+    }
+    while (b!=0);
+    b = a;
+    if (b == 1)
+      return;
+  }
+  for (i = n; i!=0 ; i--)
+    x[i] /= b;
+}
+
+
+static void wSimple(int *x, int n)
+{
+  int g, min, c, d, f, kopt, k, i;
+  int *xopt;
+  double sopt, s1, s2;
+
+  xopt = x + (n + 1);
+  kopt = k = g = 0;
+  min = 1000000;
+  for (i = n; i!=0 ; i--)
+  {
+    c = xopt[i];
+    if (c > 1)
+    {
+      if (c < min)
+        min = c;
+      if (c > k)
+        k = c;
+    }
+    else
+      g = 1;
+  }
+  k -= min;
+  if ((g==0) && (k < 4))
+    return;
+  if (k < min)
+    min = k+1;
+  sopt = (double)1.0e10;
+  for (k = min; k > 1; k--)
+  {
+    s2 = s1 = (double)0.0;
+    for(i = n; i!=0 ; i--)
+    {
+      c = xopt[i];
+      if (c > 1)
+      {
+        d = c / k;
+        d *= k;
+        f = d = c - d;
+        if (f!=0)
+        {
+          f = k - f;
+          if (f < d)
+            s2 += (double)f / (double)c;
+          else
+            s1 += (double)d / (double)c;
+        }
+      }
+    }
+    s1 += s2 + sqrt(s1 * s2);
+    s1 -= (double)0.01 * sqrt((double)k);
+    if (s1 < sopt)
+    {
+      sopt = s1;
+      kopt = k;
+    }
+  }
+  for(i = n; i!=0 ; i--)
+  {
+    x[i] = 1;
+    c = xopt[i];
+    if (c > 1)
+    {
+      d = c / kopt;
+      d *= kopt;
+      x[i] = d;
+      d = c - d;
+      if ((d!=0) && (kopt < 2 * d))
+        x[i] += kopt;
+    }
+  }
+  if (g==0)
+    wGcd(x, n);
+}
+
+
+void wNorm(int *degw, int *lpol, int npol, double *rel)
+{
+  int  i, j, ecu, ec;
+  int  *ex;
+  double *r;
+
+  ex = degw;
+  r = rel;
+  for (i = 0; i < npol; i++)
+  {
+    ecu = *ex++;
+    for (j = lpol[i] - 1; j!=0 ; j--)
+    {
+      ec = *ex++;
+      if (ec > ecu)
+        ecu = ec;
+    }
+    *r = (double)1.0 / (double)(ecu * ecu);
+    r++;
+  }
+}
